Robot description
The robot description has one source in mycobot_description/. A generator writes
every copy that the firmware, the Control page, the simulator and the Julia package
use. Do not edit a generated file: edit the source and run the generator.
| File | Format | Holds |
|---|---|---|
urdf/mycobot_280_arduino/mycobot_280_arduino.urdf.xacro |
URDF in xacro | Links, meshes, joint origins and axes; the gripper (with gripper:=true) |
config/mycobot_280_arduino/joint_limits.yaml |
ros2_control joint_limits |
Position, speed, acceleration and effort limits |
config/mycobot_280_arduino/servos.yaml |
Our own | Servo IDs, directions, models, gains, acceleration registers, servo model (ωn, ζ) |
config/mycobot_280_arduino/calibration.yaml |
Our own | This robot only: encoder corrections. Only the Julia package uses it (ENCODER_CORRECTION). |
The generator tools/gen_robot.py writes:
| Generated file | Used by |
|---|---|
mycobot_description/urdf/mycobot_280_arduino/mycobot_280_arduino.urdf |
Julia (load_mechanism), meshes as package://…/*.dae |
website/public/robot/mycobot_280_arduino.urdf |
Control page 3D view, meshes as *.glb |
mycobot_description/urdf/mycobot_280_arduino/mycobot_280_arduino_gripper.urdf |
Julia, the arm with the gripper (load_mechanism(urdf=...)) |
website/public/robot/mycobot_280_arduino_gripper.urdf |
Control page 3D view with the gripper (ArmView.setGripper(true)) |
firmware/atom_controller/robot_params.h |
Controller firmware (motion_limits.h, joint directions, gains) |
website/src/control/robot_params.ts |
Control page (protocol.ts) |
tools/robot_params.py |
Simulator (tools/atom_sim.py) |
src/robot_params.jl |
Julia package (SERVO_IDS, JOINT_SIGN, GAINS, SERVO_WN, …) |
Before 2026-10-06 the limits were written by hand in five places, and the Control page had its own copy of the URDF.
Xacro arguments
Section titled “Xacro arguments”| Argument | Default | Effect |
|---|---|---|
mesh_uri |
package://mycobot_description/urdf/mycobot_280_arduino/ |
Prefix of the mesh file names. The web copy uses "" (meshes next to the URDF). |
mesh_ext |
dae |
Mesh file type. The web copy uses glb. |
gripper |
false |
true adds the adaptive gripper at the flange (Gripper). |
The gripper part has two properties in the xacro file:
| Property | Value | Meaning |
|---|---|---|
gripper_mount_deg |
0 | Mount angle about the J6 axis, from Elephant’s mount (Mount angle) |
gripper_closed, gripper_open |
−0.7, 0.15 rad | Range of the actuated finger joint gripper_controller |
The gripper meshes are gripper_*.dae in urdf/mycobot_280_arduino/. After you add or
change a mesh, convert it for the Control page (only the named meshes):
uv run --with trimesh --with pycollada --with pillow --with scipy python tools/web_meshes.py gripper_baseChange a value
Section titled “Change a value”- Edit the xacro file or a YAML file in
mycobot_description/. - Run the generator on the laptop:
Terminal window uv run tools/gen_robot.pyuvinstalls xacro and PyYAML for the script (the script header lists them). - Commit the source and the generated files together.
- If the firmware values changed, build and update the firmware (Build, flash and update).
The Julia tests run uv run tools/gen_robot.py --check. It fails if a generated
file is not up to date. The check is skipped where uv is not installed (the Pi).
Why these formats
Section titled “Why these formats”URDF holds the kinematic tree, the meshes, the inertias and, per joint,
<limit> (lower, upper, velocity, effort), <safety_controller>,
<dynamics> (damping, friction), <calibration> (homing switch positions
only) and <mimic>. It has no acceleration limits, no sensors and no actuator
model.
| Need | Format | Why |
|---|---|---|
| Acceleration, deceleration and jerk limits | ros2_control joint_limits YAML |
The ROS standard for limits that URDF does not have. Keys: max_position, max_velocity, max_acceleration, max_deceleration, max_jerk, max_effort, each with has_*_limits. |
| YAML files next to the URDF | xacro with xacro.load_yaml |
Universal Robots (ur_description) and Franka (franka_description) do the same. |
| Per-robot calibration (later) | A YAML file per robot | Universal Robots keeps the calibrated kinematics of each robot in default_kinematics.yaml. |
| Servo data | Our own servos.yaml |
No robot description format has bus servos, registers or a position-loop model. MuJoCo’s MJCF has kp and damping, but not the acceleration limit of our servos. |
| Named poses, groups | SRDF (MoveIt) | Not used yet. Add it if a MoveIt planner is used. |
The limit values are in SI units (rad, rad/s, rad/s²), so ROS tools can read the file. The generator converts them to degrees for the firmware and the Control page.
Values and where they come from
Section titled “Values and where they come from”| Value | Source |
|---|---|
| Lengths, joint axes, meshes | Elephant’s mycobot_280_arduino.urdf (mycobot_ros), with the flange turned 45° about its axis (2025-02-16). |
| Position limits (±165, ±140, ±150, ±150, ±160°; J6 −225° to +135°) | Inside the end stops measured by hand on 2026-10-04; J6: one turn inside the gripper cable stops (2026-10-06) (Robot). |
| Speed limit 90 °/s | Our firmware (MOVE_TO, TRACK). |
| Acceleration limits 400 / 2000 °/s² | Our firmware, below the servo limits (439 / 2197 °/s², Servo dynamics). |
| Effort | Not known: the servo models are not identified. has_effort_limits: false, effort="0" in the URDF. |
| Gains, ωn, ζ | Servo dynamics (2026-10-04). |
| Gripper meshes and finger joints | Elephant’s mycobot_280m5_with_gripper_parallel.urdf (mycobot_ros), with the finger joints on the body moved 7.5 mm (Gripper). |
| Gripper mount angle | The user’s report of the mount on this arm (2026-10-06). |
Base plate (g_base) |
Elephant’s mesh, turned 90° about z (2026-10-06): on this robot the round base is mounted on the plate 90° from Elephant’s model. The 150 mm side is along x, and the plate is 10 mm toward −y (checked with the calibrated lab camera). |
| Masses and inertias | Not in the description yet (arm and gripper). |
The generated URDF gives the same forward kinematics as the URDF before 2026-10-06
(difference 0 over 200 random poses). Two small changes: the collision origin of
g_base now equals its visual origin (it was 1 cm off), and the fixed joint
g_base_to_joint1 has no <limit> element.
What Elephant’s repositories have (checked 2026-10-06)
Section titled “What Elephant’s repositories have (checked 2026-10-06)”mycobot_ros (c0d6fbe), mycobot_ros2 (d42ff61) and pymycobot (v4.0.4):
- No real dynamics data for the 280. Every
<inertial>is a placeholder (for example mass 0.1 kg and inertia 0.03 kg·m² on every link). Every MoveItjoint_limits.yamlfor the 280 has no speed or acceleration limits. - The same lengths in all 280 URDFs for Arduino and M5. Our flange is turned 45°. The ROS 1 Arduino URDF turns the whole robot 90° about the base axis.
- Joint limits: mostly ±168, ±140, ±150, ±150, −155 to +160, ±180°
(
pymycobot/robot_info.py), and other sets in other files. - No servo models, masses, payload or repeatability in the documentation.
- The SRDF has one named pose,
init_pose(all joints at 0).
- More in
calibration.yaml: the IMU mounting and accelerometer calibration, and the play of each joint (IMU and encoder errors). - Store the calibration on each ATOM, so the firmware and the Control page can use it.
inertials.yaml: masses and centres of mass from a gravity identification.- Effort limits, when the servo models are known.