Welcome to DOFBOT-Ultra repository
1. Robotic arm ROS control
Robotic Arm ROS Control
Please ensure that the web control program backend process is not running in the background. To close it, refer to the [Get Started Quickly - 2. Access the Terminal] section in [Disable the Auto-Start Web Control Backend Process]. After closing, please restart DofbotUltra!!!
Before starting this function, you need to close the web control program backend process.
1. Function Description
After the program starts, you can control the robotic arm's pose and individual servo values through ROS. This guide uses ros2 topic command-line tools to change the robotic arm's pose and individual servo values. In subsequent programs, the robotic arm is also controlled through topics.
2. Startup and Operation
2.1. Startup Command
After opening the terminal, enter the following command:
xxxxxxxxxx# Start the low-level driverros2 run dofbot_ultra_driver arm_driver2.2. Operation Steps
Start the terminal and enter the following command:
xxxxxxxxxxros2 topic list
As shown in the image above, /TargetAngle is the topic for controlling the robotic arm. We publish messages to this topic using ros2 topic tools. First, let's check the topic's related information. Enter in the terminal:
xxxxxxxxxxros2 topic info /TargetAngle
As shown in the image above, the data type of this topic is dofbot_ultra_info/ArmJoint. This is our custom message data interface. You can view the specific content of this data type with the following command:
xxxxxxxxxxros2 interface show dofbot_ultra_interface/msg/ArmJoint
As shown in the image above, here are the specific contents of the dofbot_ultra_interface/ArmJoint type data. The properties of each variable are as follows:
id: The corresponding servo ID. When controlling a single servo, you need to specify this value. The valid range is [1-6].run_time: Servo running time. This indicates the time within which the robotic arm needs to reach the specified pose or a single servo needs to reach the specified angle. Unit is ms.angle: Control angle. When controlling a single servo, you need to set the angle value after movement. The valid range is [0, 180].joints: An array of length 6. When controlling 6 servo values, write the 6 servo values into this data. The array index corresponds to each servo's ID-1. The control range for each servo angle is [0, 180].
We can test with the following commands:
To control a single servo, taking servo #1 as an example, enter in the terminal and press Enter to send:
xxxxxxxxxxros2 topic pub /TargetAngle dofbot_ultra_interface/ArmJoint "{id: 1, run_time: 1000, angle: 120.0, joints: []}"To control multiple servos, taking the robotic arm to an upward extended pose as an example, enter in the terminal:
xxxxxxxxxxros2 topic pub /TargetAngle dofbot_ultra_interface/ArmJoint "{id: 1, run_time: 1000, angle: 120.0, joints: [90, 90, 90, 90, 90, 90]}"After entering, press Enter to send the topic data. The robotic arm will move to an upward extended pose.
3. Program Flowchart

4. Core Code Analysis
Code paths:
xxxxxxxxxxRaspberry Pi: /home/yahboom/dofbot_ultra_ws/src/dofbot_ultra_driver/dofbot_ultra_driver/arm_driver.pyRDK: /home/sunrise/dofbot_ultra_ws/src/core/dofbot_ultra_driver/dofbot_ultra_driver/arm_driver.py
Import library files:
xxxxxxxxxx# Low-level driver library filefrom Arm_Lib import Arm_Device# Custom message datafrom dofbot_ultra_interface.msg import *# Import rclpy libraryimport rclpyfrom rclpy.node import NodeDefine a subscriber to subscribe to the TargetAngle topic:
xxxxxxxxxxself.sub_Arm = self.create_subscription(ArmJoint,"TargetAngle", self.Armcallback, queue_size=1000)Write a callback function to process received messages and send data to the low-level control:
xxxxxxxxxxdef Armcallback(self,msg): if not isinstance(msg, ArmJoint): print("----------") return arm_joint = ArmJoint() print("msg.joints: ",msg.joints) print("msg.joints: ",msg.run_time) if len(msg.joints) != 0: arm_joint.joints = self.cur_joints for i in range(2): print("--------------------------") self.Arm.Arm_serial_servo_write6(msg.joints[0], msg.joints[1],msg.joints[2],msg.joints[3],msg.joints[4],msg.joints[5],time=msg.run_time) self.cur_joints = list(msg.joints) self.ArmPubUpdate.publish(arm_joint) #time.sleep(0.01) else: arm_joint.id = msg.id arm_joint.angle = msg.angle for i in range(2):