New task
Recently, I was assigned a new task: to enable teleoperation for a compact mobile robot. This little bot boasts two motorized wheels (equipped with Maxon EPOS4 motors) and a set of caster wheels. In the preceding months, my colleagues have installed ROS2 (Humble) on the robot’s onboard computer. They also git cloned the ros2_canopen stack and attempted to control the robot using the “diff_drive_controller” — following the example “Pilz Manipulator PRBT 6” in the official documentation of ros2_canopen. Despite their efforts, the robot remained stubbornly stationary.
Then, the torch has been passed to me. I’ve been asked to continue this work, unravel the mystery, and breathe life into our mini mobile marvel. Let’s get those wheels turning!
Navigating the ROS2_CANopen Maze: Debugging Low-Level Robot Control
Embarking on this task, I delved into the ros2_canopen documentation. Candidly, it wasn’t the most user-friendly read. Consequently, I found myself occasionally spelunking through the source code to grasp its concepts, overall structure, and various parameter configurations.
Next, I created a package called single_epos4_canopen — a modest creation aimed at controlling a solitary Epos4 motor using ros2_canopen. My inspiration? Well, this lightweight package sidesteps high-level features like ros2_control and robot description. Instead, it zeroes in on the nitty-gritty: CAN communication debugging.
With single_epos4_canopen in action, I managed to make wheel rotate by calling ros2 service call /single_motor/target canopen_interfaces/srv/COTargetDouble “{ target: 10.0 }”
service (thanks to our default “velocity mode”). Ahoy, success! This, at least, confirms that our CAN network is fine.
And when it’s time to halt the motion, ros2 service call /single_motor/halt std_srvs/srv/Trigger
does the trick. Similarly I can call nmt_state_reset
service to restart the NMT of the node whose Heartbeat is configured to be sent every 1000ms.
CanOpen frames analysis
Thanks to the single_epos4_canopen package, I can monitor and analyze the CanOpen frames by calling
1 | candump can0 |
(sorry I was not allowed to share the images).
By conducting tests on respectively each CanOpen node and checking carefully the CanOpen frames, I found that issues come from the OD definitions. Updating the wrong OD entries via Epos Studio finally fixed those issues.
Use ros2_control with ros2_canopen
By following this example, I created the package for controlling both motors with help of diff_drive_controller in ros2_control. After having been struggling with the configurations and tests for multiple days, and by making some workaround to fix errors in some function for handling init, finally I can control the robot with joystick:
Simulation
Afterward, I spent 2 more days to update the robot description file, added some gazebo control and sensor plugins and make the simulated bot tele-operable in Gazebo simulator via “teleop_twist_keyboard”:
Future work
For some reason, this project has been paused, though I would like to continue to achieve autonomous navigation and fleet control on this robot. Probably there will be no more updates about future developments :(