Environment Setup
Installing the ROS2 Environment
Refer to ROS2 Environment Setup
Installing p1_ros2
Refer to Installing ultraArm P1 p1_ros2
Execute the following command to install the ultraArm P1 ROS2 code:
$ cd ~/colcon_ws/src
# For the humble branch
$ git clone -b p1-humble https://github.com/elephantrobotics/p1_ros2.git
# For the foxy branch
$ git clone -b p1 https://github.com/elephantrobotics/p1_ros2.git
$ cd ~/colcon_ws
$ colcon build
$ source ~/colcon_ws/install/setup.bash
$ sudo echo 'source ~/colcon_ws/install/setup.bash' >> ~/.bashrc
Controlling the Robotic Arm
Note: The ultraArm_P1_lib driver library version must be greater than 4.0.4.
Preparation Before Use
Before using the example functions, please ensure the following hardware and environment are ready:
Hardware Equipment
ultraArm P1 robotic arm
Power adapter
USB Type-C serial cable
Software and Environment
PC virtual machine Ubuntu 20.04 system
Python 3.6 or later is installed
The
ultraArm_P1_liblibrary is installed (installed via the terminal commandpip install ultraArm_P1_lib)Ensure the ultraArm P1 is correctly powered on, the serial cable is connected, and the virtual machine system can detect the serial port number.
Verification: Verify if the robotic arm's serial port exists. Enter the following in the terminal:
ls /dev/tty*If the output serial port information includes
/dev/ttyACM*or/dev/ttyUSB*, the serial port has been detected.- Serial Port Permissions: If the serial port exists, execute permissions need to be granted:
sudo chmod 777 /dev/ttyUSB* # or sudo chmod 777 /dev/ttyACM*
1 Slider Control
Open the command line and run:
# Default serial port name is "/dev/ttyUSB0", baud rate is 1000000.
ros2 launch ultraarm_p1 slider_control.launch.py port:=/dev/ttyUSB0 baud:=1000000
This will open rviz2 and a slider component, you will see something like the following:

Then, you can control the model's movement in rviz2 by dragging the slider. The real ultraArm robot will move accordingly.
Please note: Since the robotic arm moves to the model's current position when you input a command, please ensure that the model in rviz is not clipping through the model before using the command.
Do not drag the slider quickly after connecting the robotic arm to prevent damage.
2 Model Following
In addition to the above control, we can also make the model follow the movement of the real robotic arm.
Open a command line and run:
# Default serial port name is "/dev/ttyUSB0", baud rate is 1000000.
ros2 launch ultraarm_p1 p1_follow.launch.py port:=/dev/ttyUSB0 baud:=1000000
After successful execution, all joints of the robotic arm will be released. It will open rviz to display the model following effect. At this point, dragging the joints of the real robotic arm will cause the simulation model to follow the movement of the real robotic arm.

After successful execution, you need to press and hold the end effector button on the machine to drag the joints. The terminal output information is as follows:
[INFO] [follow_display-2]: process started with pid [22937]
[INFO] [rviz2-3]: process started with pid [22939]
[robot_state_publisher-1] Parsing robot urdf xml string.
[robot_state_publisher-1] Link base_link had 1 children
[robot_state_publisher-1] Link J1_LINK had 2 children
[robot_state_publisher-1] Link J2_Link1 had 1 children
[robot_state_publisher-1] Link J2_Link4 had 3 children
[robot_state_publisher-1] Link FIX1 had 0 children
[robot_state_publisher-1] Link FIX3 had 1 children
[robot_state_publisher-1] Link J3_LIink2 had 1 children
[robot_state_publisher-1] Link J3_Link4 had 0 children
[robot_state_publisher-1] Link J3_Link1 had 1 children
[robot_state_publisher-1] Link J3_Link3 had 2 children
[robot_state_publisher-1] Link FIX2 had 0 children
[robot_state_publisher-1] Link J4_Link had 0 children
[robot_state_publisher-1] Link J2_Link2 had 1 children
[robot_state_publisher-1] Link J2_Link3 had 0 children
[robot_state_publisher-1] [INFO] [1764754285.821859506] [robot_state_publisher]: got segment FIX1
[robot_state_publisher-1] [INFO] [1764754285.827021946] [robot_state_publisher]: got segment FIX2
[robot_state_publisher-1] [INFO] [1764754285.827126900] [robot_state_publisher]: got segment FIX3
[robot_state_publisher-1] [INFO] [1764754285.827155906] [robot_state_publisher]: got segment J1_LINK
[robot_state_publisher-1] [INFO] [1764754285.827172589] [robot_state_publisher]: got segment J2_Link1
[robot_state_publisher-1] [INFO] [1764754285.827190463] [robot_state_publisher]: got segment J2_Link2
[robot_state_publisher-1] [INFO] [1764754285.827211364] [robot_state_publisher]: got segment J2_Link3
[robot_state_publisher-1] [INFO] [1764754285.827226954] [robot_state_publisher]: got segment J2_Link4
[robot_state_publisher-1] [INFO] [1764754285.827242454] [robot_state_publisher]: got segment J3_LIink2
[robot_state_publisher-1] [INFO] [1764754285.827261692] [robot_state_publisher]: got segment J3_Link1
[robot_state_publisher-1] [INFO] [1764754285.827281400] [robot_state_publisher]: got segment J3_Link3
[robot_state_publisher-1] [INFO] [1764754285.827297331] [robot_state_publisher]: got segment J3_Link4
[robot_state_publisher-1] [INFO] [1764754285.827312000] [robot_state_publisher]: got segment J4_Link
[robot_state_publisher-1] [INFO] [1764754285.827331908] [robot_state_publisher]: got segment base_link
[robot_state_publisher-1] [INFO] [1764754285.827350645] [robot_state_publisher]: got segment world
[rviz2-3] [INFO] [1764754286.785808416] [rviz2]: Stereo is NOT SUPPORTED
[rviz2-3] [INFO] [1764754286.786219374] [rviz2]: OpenGl version: 3.1 (GLSL 1.4)
[rviz2-3] [INFO] [1764754286.960518823] [rviz2]: Stereo is NOT SUPPORTED
[follow_display-2] [INFO] [1764754287.420866552] [follow_display]: port:/dev/ttyUSB0, baud:115200
[rviz2-3] Parsing robot urdf xml string.
[follow_display-2] [INFO] [1764754288.463556416] [follow_display]: All joint released.
[follow_display-2]
[follow_display-2] [INFO] [1764754288.601436573] [follow_display]: Publishing ...
[follow_display-2] current ultraArm_P1_lib library version: 4.0.4b3
[follow_display-2] ultraArm_P1_lib library version meets the requirements!
3 GUI Control
Building upon the previous features, this package also provides a simple graphical user interface control interface. This approach means that the actual robotic arms are interconnected; please connect to ultraArm.
Open command line:
# Default serial port name is "/dev/ttyUSB0", baud rate is 115200.
ros2 launch ultraarm_p1 simple_gui.launch.py port:=/dev/ttyUSB0 baud:=115200

After successful execution, the terminal output is as follows:
[INFO] [launch]: Default logging verbosity is set to INFO
[INFO] [robot_state_publisher-1]: process started with pid [23417]
[INFO] [listen_real_service-2]: process started with pid [23419]
[INFO] [simple_gui-3]: process started with pid [23421]
[INFO] [rviz2-4]: process started with pid [23423]
[robot_state_publisher-1] Parsing robot urdf xml string.
[robot_state_publisher-1] Link base_link had 1 children
[robot_state_publisher-1] Link J1_LINK had 2 children
[robot_state_publisher-1] Link J2_Link1 had 1 children
[robot_state_publisher-1] Link J2_Link4 had 3 children
[robot_state_publisher-1] Link FIX1 had 0 children
[robot_state_publisher-1] Link FIX3 had 1 children
[robot_state_publisher-1] Link J3_LIink2 had 1 children
[robot_state_publisher-1] Link J3_Link4 had 0 children
[robot_state_publisher-1] Link J3_Link1 had 1 children
[robot_state_publisher-1] Link J3_Link3 had 2 children
[robot_state_publisher-1] Link FIX2 had 0 children
[robot_state_publisher-1] Link J4_Link had 0 children
[robot_state_publisher-1] Link J2_Link2 had 1 children
[robot_state_publisher-1] Link J2_Link3 had 0 children
[robot_state_publisher-1] [INFO] [1764754690.688488026] [robot_state_publisher]: got segment FIX1
[robot_state_publisher-1] [INFO] [1764754690.692047048] [robot_state_publisher]: got segment FIX2
[robot_state_publisher-1] [INFO] [1764754690.692120163] [robot_state_publisher]: got segment FIX3
[robot_state_publisher-1] [INFO] [1764754690.692146702] [robot_state_publisher]: got segment J1_LINK
[robot_state_publisher-1] [INFO] [1764754690.692163713] [robot_state_publisher]: got segment J2_Link1
[robot_state_publisher-1] [INFO] [1764754690.692178420] [robot_state_publisher]: got segment J2_Link2
[robot_state_publisher-1] [INFO] [1764754690.692192827] [robot_state_publisher]: got segment J2_Link3
[robot_state_publisher-1] [INFO] [1764754690.692207404] [robot_state_publisher]: got segment J2_Link4
[robot_state_publisher-1] [INFO] [1764754690.692222431] [robot_state_publisher]: got segment J3_LIink2
[robot_state_publisher-1] [INFO] [1764754690.692237529] [robot_state_publisher]: got segment J3_Link1
[robot_state_publisher-1] [INFO] [1764754690.692255362] [robot_state_publisher]: got segment J3_Link3
[robot_state_publisher-1] [INFO] [1764754690.692276822] [robot_state_publisher]: got segment J3_Link4
[robot_state_publisher-1] [INFO] [1764754690.692296618] [robot_state_publisher]: got segment J4_Link
[robot_state_publisher-1] [INFO] [1764754690.692311626] [robot_state_publisher]: got segment base_link
[robot_state_publisher-1] [INFO] [1764754690.692326063] [robot_state_publisher]: got segment world
[rviz2-4] [INFO] [1764754692.337228590] [rviz2]: Stereo is NOT SUPPORTED
[rviz2-4] [INFO] [1764754692.337892341] [rviz2]: OpenGl version: 3.1 (GLSL 1.4)
[rviz2-4] [INFO] [1764754692.677950762] [rviz2]: Stereo is NOT SUPPORTED
[listen_real_service-2] [INFO] [1764754693.745880907] [listen_real_service]: port:/dev/ttyUSB0, baud:115200
[rviz2-4] Parsing robot urdf xml string.
Then, input the relevant angle and coordinate information in the GUI interface and click the corresponding button to achieve synchronized movement between the real machine and the simulation model.
4 Keyboard Control
Keyboard control functionality has been added to the ultraarm_p1 package and is synchronized in real time in rviz2. This functionality relies on the Python API, so ensure it is connected to the actual robotic arm.
Open the command line and run:
# Default serial port name is "/dev/ttyUSB0", baud rate is 1000000.
ros2 launch ultraarm_p1 teleop_keyboard.launch.py port:=/dev/ttyUSB0 baud:=1000000
The running effect is as follows:

The command line will output ultraArm information, as follows:
[INFO] [launch]: Default logging verbosity is set to INFO
[INFO] [robot_state_publisher-1]: process started with pid [26338]
[INFO] [listen_real_service-2]: process started with pid [26340]
[INFO] [rviz2-3]: process started with pid [26342]
[robot_state_publisher-1] Parsing robot urdf xml string.
[robot_state_publisher-1] Link base_link had 1 children
[robot_state_publisher-1] Link J1_LINK had 2 children
[robot_state_publisher-1] Link J2_Link1 had 1 children
[robot_state_publisher-1] Link J2_Link4 had 3 children
[robot_state_publisher-1] Link FIX1 had 0 children
[robot_state_publisher-1] Link FIX3 had 1 children
[robot_state_publisher-1] Link J3_LIink2 had 1 children
[robot_state_publisher-1] Link J3_Link4 had 0 children
[robot_state_publisher-1] Link J3_Link1 had 1 children
[robot_state_publisher-1] Link J3_Link3 had 2 children
[robot_state_publisher-1] Link FIX2 had 0 children
[robot_state_publisher-1] Link J4_Link had 0 children
[robot_state_publisher-1] Link J2_Link2 had 1 children
[robot_state_publisher-1] Link J2_Link3 had 0 children
[robot_state_publisher-1] [INFO] [1764756153.570946274] [robot_state_publisher]: got segment FIX1
[robot_state_publisher-1] [INFO] [1764756153.571195782] [robot_state_publisher]: got segment FIX2
[robot_state_publisher-1] [INFO] [1764756153.571221292] [robot_state_publisher]: got segment FIX3
[robot_state_publisher-1] [INFO] [1764756153.571237033] [robot_state_publisher]: got segment J1_LINK
[robot_state_publisher-1] [INFO] [1764756153.571251792] [robot_state_publisher]: got segment J2_Link1
[robot_state_publisher-1] [INFO] [1764756153.571266390] [robot_state_publisher]: got segment J2_Link2
[robot_state_publisher-1] [INFO] [1764756153.571280949] [robot_state_publisher]: got segment J2_Link3
[robot_state_publisher-1] [INFO] [1764756153.571295597] [robot_state_publisher]: got segment J2_Link4
[robot_state_publisher-1] [INFO] [1764756153.571310066] [robot_state_publisher]: got segment J3_LIink2
[robot_state_publisher-1] [INFO] [1764756153.571324303] [robot_state_publisher]: got segment J3_Link1
[robot_state_publisher-1] [INFO] [1764756153.571338611] [robot_state_publisher]: got segment J3_Link3
[robot_state_publisher-1] [INFO] [1764756153.571353450] [robot_state_publisher]: got segment J3_Link4
[robot_state_publisher-1] [INFO] [1764756153.571367488] [robot_state_publisher]: got segment J4_Link
[robot_state_publisher-1] [INFO] [1764756153.571382958] [robot_state_publisher]: got segment base_link
[robot_state_publisher-1] [INFO] [1764756153.571403939] [robot_state_publisher]: got segment world
[rviz2-3] [INFO] [1764756154.449688149] [rviz2]: Stereo is NOT SUPPORTED
[rviz2-3] [INFO] [1764756154.451433555] [rviz2]: OpenGl version: 3.1 (GLSL 1.4)
[rviz2-3] [INFO] [1764756154.611921792] [rviz2]: Stereo is NOT SUPPORTED
[listen_real_service-2] [INFO] [1764756155.102106356] [listen_real_service]: port:/dev/ttyUSB0, baud:115200
[rviz2-3] Parsing robot urdf xml string.
Next, open another command line:
ros2 run ultraarm_p1 teleop_keyboard
You will see the following output in the terminal:
ultraArm P1 Teleop Keyboard Controller
---------------------------
Movimg options(control coordinations [x,y,z,rx]):
w(x+)
a(y-) s(x-) d(y+)
z(z-) x(z+)
u(rx+) j(rx-)
+/- : Increase/decrease movement step size
Other:
1 - Go to init pose
2 - Go to home pose
3 - Resave home pose
q - Quit
currently:speed: 50 change percent: 5
In this terminal, you can control the state and move the robotic arm using the keys in the command line.
Note: After inputting "2" to return the robotic arm to the starting point, and then performing other coordinate control operations, the terminal will display the following prompt:
[WARN] [1758001794.385321]: Coordinate control disabled. Please press '2' first.
[INFO] [1758001804.552778]: Home pose reached. Coordinate control enabled.
[INFO] [1758001817.069637]: Home pose reached. Coordinate control enabled.
[WARN] [1758001836.301070]: Returned to zero. Press '2' to enable coordinate control.
[WARN] [1758001848.830702]: Coordinate control disabled. Please press '2' first.
[INFO] [1758001863.383565]: Home pose reached. Coordinate control enabled.
[WARN] [1758001933.596504]: Returned to zero. Press '2' to enable coordinate control.
[WARN] [1758001942.051899]: Coordinate control disabled. Please press '2' first.