1 of 19

2 of 19

ReBot Arm B601-DM

Developer Workshop

SDK Deep-Dive · Teleoperation · Camera Integration · Dataset Recording

Pinocchio Kinematics

6-DOF Control

LeRobot Integration

Python 3.10+ · Ubuntu 22.04+ · USB2CAN / CAN Interface

3 of 19

Workshop Agenda

01

SDK Overview

Architecture, project structure, core modules

02

Debug Tools

Single motor console · Zero calibration & monitor

03

Kinematics Examples

Forward kinematics · Inverse kinematics solver

04

Real Machine Control

IK control · Trajectory planning · Gravity comp.

05

Find Ports & Cameras

lerobot-find-port · lerobot-find-cameras

06

Calibration

Follower & leader arm calibration steps

07

Recording with Camera

lerobot-record · dataset collection & tips

4 of 19

01 · SDK OVERVIEW

Installation & Hardware Setup

1

Install uv package manager

curl -LsSf https://astral.sh/uv/install.sh | sh

2

Clone & sync reBot SDK

git clone https://github.com/vectorBH6/reBotArm_control_py

cd reBotArm_control_py && uv sync

3

Clone & install LeRobot

mkdir rebot_lerobot

cd rebot_lerobot

git clone https://github.com/Seeed-Projects/lerobot.git

git clone https://github.com/Seeed-Projects/lerobot-teleoperator-rebot-arm-102.git

git clone https://github.com/Seeed-Projects/lerobot-robot-seeed-b601.git

pip install -e ./lerobot

pip install -e ./lerobot-teleoperator-rebot-arm-102

pip install -e ./lerobot-robot-seeed-b601

pip install motorbridge

5 of 19

FIND PORTS

Find Serial Ports

Identify the correct port for the arm

Grand Permissions - sudo chmod 666 /dev/tty*

Run - lerobot-find-port

Remove the USB cable from your MotorsBus and press Enter when done.

It will display your port -

Change your port in reBotArm_control_py/config/arm.yaml

6 of 19

01 · SDK OVERVIEW

Project Architecture & Core Modules

Built on Pinocchio + MotorBridge SDK

actuator/

Low-level motor

drivers & abstraction

layer for Damiao

and RobStride motors

kinematics/

Pinocchio-based FK/IK

solver, URDF loader,

and SE(3) math utilities

controllers/

High-level arm

controllers: joint-space,

task-space, and

real-time loops

trajectory/

SE(3) geodesic

trajectory planner

with CLIK tracking

& time-scaling

Key Supporting Files

config/robot.yaml

urdf/rebot.urdf

pyproject.toml

7 of 19

02 · DEBUG TOOLS

1_damiao_text.py — Single Motor Console

Direct MotorBridge SDK testing with interactive commands

Purpose: Test individual Damiao motors across three

control modes before full arm deployment

$ terminal

uv run python example/1_damiao_text.py

Interactive Command

Description

mit <pos> [vel kp kd tau]

MIT position-velocity mode

posvel <pos_deg> [vlim]

POS_VEL control mode

vel <vel_rad_s>

Pure velocity mode

enable / disable

Motor enable/disable

set_zero

Set current pos as zero

state

View current motor state

3 Control Modes

MIT Mode

Full parameter control

pos + vel + kp + kd + tau

Best for: tuning gains

POS_VEL Mode

Velocity-limited position

Simpler interface

Best for: smooth motion

Velocity Mode

Continuous rotation

Speed in rad/s

Best for: conveyor / wheel

8 of 19

02 · DEBUG TOOLS

2_zero_and_read.py — Zero Calibration & Angle Monitor

Automatically zeros all joints and displays real-time joint angles

$ terminal

uv run python example/2_zero_and_read.py

Auto Zero All Joints

Sets current position of each joint

as the zero reference in one command

Real-time Angle Display

Continuous terminal readout of

all 6 joint angles while arm moves

Hardware Sanity Check

Verify motor communication

before running higher-level examples

When to Use

Always run after physical

re-configuration or if joints drift

9 of 19

03 · KINEMATICS TESTS

5_fk_test.py — Forward Kinematics Test

Calculate end-effector pose from joint angles using Pinocchio

$ terminal

uv run python example/5_fk_test.py

> 0 0 0 0 0 0

> 45 -30 15 -60 90 180

INPUT

6 Joint Angles

(degrees)

θ₁ θ₂ θ₃

θ₄ θ₅ θ₆

FK

Solver

OUTPUT

Position (X, Y, Z)

in meters

Rotation Matrix

3×3

Euler Angles

Roll / Pitch / Yaw°

What is Forward Kinematics?

Given a set of joint angles, FK computes where the end-effector ends up in 3D Cartesian space.

Pinocchio loads the URDF model to handle

all the link transforms automatically.

10 of 19

03 · KINEMATICS TESTS

6_ik_test.py — Inverse Kinematics Solver

Solve joint angles from desired Cartesian end-effector pose

$ terminal

uv run python example/6_ik_test.py

> 0.25 0.0 0.15 # Position only

> 0.25 0.0 0.15 0 0 0 # Position + Orientation

Position Only

<x> <y> <z>

IK solver chooses

optimal orientation

Position + Orientation

<x> <y> <z> <roll> <pitch> <yaw>

Full 6-DOF target

pose specification

IK Solver Notes

Position in meters (x, y, z)

Orientation in degrees (roll, pitch, yaw)

Uses CLIK (Closed-Loop IK) internally

Multiple solutions may exist — solver returns closest to current config

Requires valid URDF in /urdf/ directory

11 of 19

04 · REAL MACHINE CONTROL

7_arm_ik_control.py & 8_arm_traj_control.py

Real-time IK control and SE(3) trajectory planning on hardware

7_arm_ik_control.py — IK Real-time Control

x y z [roll pitch yaw]

Move to Cartesian target

state

Current & target state

pos

End-effector position

q / quit / exit

Stop & disconnect

Example usage:

> 0.3 0.0 0.2

> 0.3 0.1 0.25 0 0.5 0

8_arm_traj_control.py — Trajectory Planning

Input format:

x y z [roll pitch yaw] [duration]

x, y, z

Target position (meters)

roll, pitch, yaw

Orientation (radians)

duration

Move time in seconds (def: 2.0)

SE(3) geodesic trajectory + CLIK tracking

ensures smooth, collision-free motion.

12 of 19

04 · REAL MACHINE CONTROL

9_gravity_compensation.py

Pinocchio dynamics model for real-time gravity feedforward torque

$ terminal

uv run python example/9_gravity_compensation.py

# Output: real-time torque per joint (N·m) — Ctrl+C to stop

Control Law

τ = g(q) ← Gravity feedforward torque

pos = current motor position (tracks self)

kp = 2, kd = 1 ← Unified stiffness/damping

"Floating" Posture

Arm stays in any position against

gravity without falling under its own weight

Manual Positioning

Physically move the arm to any

angle — it holds position on release

Torque Readout

Terminal prints expected torque

for every joint in real-time (N·m)

How It Works

Pinocchio computes g(q), the gravity

torque vector at the current joint

configuration q.

This is injected as feedforward τ so

the arm's motors only need to

counteract gravity — not hold rigid.

Result: a compliant arm that feels

almost weightless when pushed,

yet holds any posture when released.

13 of 19

Part 2

Teleoperation

Setup

Find Ports · Find Cameras · Calibration · Recording

14 of 19

05 · PORTS & CAMERAS

Find Camera Indices

Use lerobot-find-cameras to enumerate all connected cameras

$ terminal

lerobot-find-cameras opencv

# For Intel RealSense:

lerobot-find-cameras realsense

sample output

--- Detected Cameras ---

Camera #0:

Name: OpenCV Camera @ 0

Type: OpenCV

Id: 0

Default: 1920×1080 @ 15 fps

(more cameras...)

Camera Index

Use the Id value (last digit)

as index_or_path in robot.cameras

Captured Images

Check ~/lerobot/outputs/captured_images/

to verify each camera's view

USB Hubs Warning

Avoid connecting cameras through

USB hubs — use direct ports only

macOS RealSense

May need sudo if you get

'failed to set power state' error

15 of 19

06 · CALIBRATION

Step 2 — Arm Calibration

Follower (B601-DM) auto-calibrates; leader (reBot 102) needs manual steps

Follower Arm — B601-DM

Auto-calibrates on every LeRobot run

Before starting, place the B601-DM in

the zero position with gripper fully closed.

sudo chmod 666 /dev/ttyACM*

Calibration data stored in:

~/.cache/huggingface/lerobot/

calibration/robots/

To recalibrate: delete files under calibration/robots/ and rerun

Leader Arm — reBot 102

1. Place reBot 102 in zero position (shown in wiki)

2. Grant port permissions:

sudo chmod 666 /dev/ttyUSB0

3. Run calibration command:

$ terminal

lerobot-calibrate \

--teleop.type=rebot_arm_102_leader \

--teleop.port=/dev/ttyUSB0 \

--teleop.id=rebot_arm_102_leader

Hold still → press Enter → calibration complete.

Verify with read_raw_angles.py — all joints should output 0.00 at zero position.

16 of 19

07 · DATASET RECORDING

Step 3 — Teleoperate with Camera Preview

Verify camera views and arm connectivity before recording

$ terminal

lerobot-teleoperate \

--robot.type=seeed_b601_dm_follower \

--robot.port=/dev/ttyACM0 \

--robot.id=follower1 \

--robot.can_adapter=damiao \

--robot.cameras="{ front: {type: opencv, index_or_path: 0,

width: 640, height: 480, fps: 30, fourcc: \"MJPG\"}}" \

--teleop.type=rebot_arm_102_leader \

--teleop.port=/dev/ttyUSB0 \

--teleop.id=rebot_arm_102_leader \

--display_data=true

MJPG Compression

Use fourcc: MJPG for bandwidth efficiency;

supports 3× cameras at 1920×1080 @ 30fps

Multi-Camera

Add extra cameras by appending more

entries to --robot.cameras with their index

Display Data

--display_data=true shows live

camera feeds + joint state on screen

joint_directions — important tuning

--teleop.joint_directions='{"shoulder_pan":-1,"shoulder_lift":-1,"elbow_flex":1,

"wrist_flex":1,"wrist_yaw":1,"wrist_roll":-1,"gripper":-4}'

17 of 19

07 · DATASET RECORDING

lerobot-record — Dataset Collection

Record demonstration episodes for imitation learning

$ terminal

lerobot-record \

--robot.type=seeed_b601_dm_follower \

--robot.port=/dev/ttyACM0 --robot.id=follower1 \

--robot.can_adapter=damiao \

--robot.cameras="{ front: {type: opencv, index_or_path: 0,

width: 640, height: 480, fps: 30, fourcc: \"MJPG\"}}" \

--teleop.type=rebot_arm_102_leader \

--teleop.port=/dev/ttyUSB0 --teleop.id=rebot_arm_102_leader \

--display_data=true \

--dataset.repo_id=seeed_rebot_b601_dm/test \

--dataset.num_episodes=5 \

--dataset.single_task="Grab the black cube" \

--dataset.push_to_hub=false \

--dataset.episode_time_s=30 \

--dataset.reset_time_s=30

→ next episode ← re-record ESC stop & upload

Key Parameters

num_episodes

Episodes to record

episode_time_s

Seconds per episode

reset_time_s

Reset time between

push_to_hub

Upload to HuggingFace

single_task

Task description text

resume=true

Resume interrupted recording

Saved → ~/.cache/huggingface/lerobot/

18 of 19

07 · DATASET RECORDING

Recording Best Practices

Tips for collecting high-quality demonstration data

✓ DO

Record ≥50 episodes (≥10 per location variant)

Keep cameras fixed during entire dataset

Maintain identical grasping technique across demos

Ensure manipulated objects are always visible

Start simple — master one location before adding variations

✗ DON'T

Don't move cameras mid-dataset

Don't mix inconsistent behaviors

Don't connect cameras through USB hubs

Don't pause mid-collection (breaks mean/var calc)

Avoid rapidly changing backgrounds or lighting

Rule of thumb: You should be able to do the task yourself by only looking at the camera images on screen.

19 of 19

Workshop Summary

01–02

SDK Modules + Debug Tools

actuator · kinematics · controllers · trajectory

1_damiao_text.py · 2_zero_and_read.py

03–04

Kinematics & Machine Control

5_fk_test · 6_ik_test · 7_ik_control

8_traj_control · 9_gravity_compensation

05

Find Ports & Cameras

Identify /dev/ttyUSB* · /dev/ttyACM*

lerobot-find-cameras opencv

06

Calibration

Auto-calibrate follower · Manual calibrate leader

lerobot-calibrate

07

Record with Camera

lerobot-teleoperate · lerobot-record

≥50 episodes · MJPG format

github.com/vectorBH6/reBotArm_control_py · wiki.seeedstudio.com/rebot_arm_b601_dm_lerobot