One of the frustrations of using other people’s code is the need to personalize it for your robot. For example the ROS gopigo3_node offered on GitHub (and used in the “Hands On ROS …” book) includes “ROS topics” to control the two possible servos of the GoPiGo3.
Depending on the particular servo ModRobotics happens to send you, the distance sensor may not point exactly forward when the servo is commanded with a pulse width half of the default pulse width limits (because there are only so many teeth on the servo shaft and “control horn sensor mount” the sensor).
The ROS(1) gopigo3_node code has CONSTANTS for pulse width limits but they are shared by both servos, difficult to determine, and you must “touch” the source code to change them.
Additionally, depending where you mount the servo kit, the distance sensor may not allow for the full 180 degree limit to limit positions, and the ROS gopigo3_node assumes full travel is possible.
These limitations mean that the ROS gopigo3_node software will not point to center when commanded with:
center servo:
$ ros2 topic pub -1 /servo/position/S1 std_msgs/msg/Float64 ‘{data: -0.0}’
And may stall the servo, drawing max current when commanded to point right 90 deg:
$ ros2 topic pub -t 1 /servo/position/S1 std_msgs/msg/Float64 '{data: -1.57}
As a ROS2 learning task, I chose to learn how to parameterize the pulse width limits and the sector width so that a ROS2 gopigo3_node user will not have to touch the source code.
It was more complicated that I had hoped, but I finally got it working this morning for the four cases:
- default settings for three values for two servos
- parameter values passed at “run” invocation
- parameter file name passed at “run” invocation
- parameters set later during node execution
It has been frustrating to be learning at the same time I’m migrating someone else’s code, but it really feels great when I get a feature working.
- Start node with parameter file
$ ros2 run ros2_gopigo3_node gopigo3_node --ros-args --params-file ./src/ros2_gopigo3_node/gopigo3_node_params.yaml &
==================================
GoPiGo3 info:
Manufacturer : Dexter Industries
Board : GoPiGo3
Serial Number : 56ECD67E5152415447202020FF192614
Hardware version: 3.x.x
Firmware version: 1.0.0
GoPiGo3 Configuration:
(Using default values or ~/Dexter/gpg3_config.json if present)
WHEEL_DIAMETER: 66.770 mm
WHEEL_BASE_WIDTH: 106.140 mm
ENCODER_TICKS_PER_ROTATION: 16 (per one motor revolution)
MOTOR_GEAR_RATIO: 120 (motor revolutions per wheel revolution)
MOTOR_TICKS_PER_DEGREE: 5.33 (of wheel rotation)
Node Version: 0.5
Rate: 30 hz
Servo1 PulseWidths L: 2094 R: 750 <--- Set from param file
Servo1 Total Sector Width: 2.443 radians <---
Servo2 PulseWidths L: 2425 R: 575 <--- Defaults
Servo2 Total Sector Width: 3.14 radians
==================================
- Test servo parameter clipping to sector width:
- Command to -90 deg should clip to -70 degrees per parameter limits:
$ ros2 topic pub -1 /servo/position/S1 std_msgs/msg/Float64 '{data: -1.57}'
publisher: beginning loop
publishing #1: std_msgs.msg.Float64(data=-1.57)
...
set_servo_angle(servo1): angle: -1.570 clipped angle: -1.222 pulse: 750