I think I will write step by step down each ROS2 node I implemented, what they are doing, what my thoughts were and why I picked exactly the message I picked.
The first one is going to be one which is essential for our direct hardware communication. This is the so calld 'motor_control'-Node. This node accepts motor commands with which the servo motors can be controlled.
Each servo motor has a unique id and name. I am not entirely sure if this is overkill and just and ID would be enough, but I think atleast for RVIZ I need a name. So I just got both for each motor.
Most logic from this node was inspired from a ros node by hansonrobotics, which I found on github. My first intention was to completely port this node to ROS2, but since I want to use the Bluepill-Controller later on (I am using a Pololu Maestro right now), I just stripped it down to the bare minimum I actually need.
It just consists of two classes. One for the motors and one for the controller. The first one is just a simple data class.
The node consists of each a simple publisher and subscriber.
The subscriber listens on the topic '/motor_command' and accepts a MotorCommand.msg which consists of the joint name, the position, speed and acceleration. Speed and acceleration are not used right now. They get default values. And apart from that this subscriber does exactly what you would think of it.
The publisher publishes to '/joint_states' all current positions of every joint. This is needed for visualization in RVIZ and later inverse kinematics calculations.
This node needs some default values for each joint as a parameter. These are noted down in the robot_params.yaml found in the root of the workspace and has the following structure:
motor_node: ros__parameters: port_name : "/dev/ttyACM0" topic_name : "motor_command" hw_connected: false motor_names: ["base_to_coxa_joint", "coxa_to_femur_joint", "femur_to_tibia_joint"] motors: base_to_coxa_joint: motor_id: 0 init: 1500 min_pulse: 500 max_pulse: 2500 min_angle: -1.5708 max_angle: 1.5708 offset: 0.7854 inverted: True
Obvious, just the port name for the controller
The topic on which should be listened
A boolean value if there is actual hardware connected. This is used for if I want to just visualize things in RVIZ and I do not have the hardware present.
A list of all following motors
A list of the above listed motors with the id, an init value, min and max pulse as well as the angles. There can also be an offset, if any is needed. Each motor can also be inverted, which then just flips the current value to the equivalent opposite.
To start the node you just have to write the following:
ros2 run qrb_motors motor_control --params:=robot_params.yaml
Now there should be a topic /motor_commands available, to which you can publish the needed motor states.
The node will then publish all of them to /joint_states, as previously described.