Skip to content

About

Repo for the UnoQWorshop, hsoting a ReachyMini on a SeeedStudio mision controller (raspberrypi) exposed locally to an MQTT server. The UnoQ can trigger actions via MQTT to move the Reachy mini

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

2 Commits

Folders and files

Repository files navigation

ReachyMini MQTT Bridge — UnoQ Workshop

A Python bridge that exposes ReachyMini robot control over MQTT. Arduino Uno Q participants connect to a local mosquitto broker and control the robot by publishing JSON messages.


Setup

# Activate the ReachyMini virtual environment
source ~/Documents/ReachyMini/reachy_mini_env/bin/activate

# Install dependencies
pip install paho-mqtt scipy

# Run the bridge (daemon must be running first)
cd ~/Documents/ReachyMiniServer.UnoQWorkshop
python -m bridge.main

Or use the convenience script:

./run_bridge.sh
./run_bridge.sh --log-level DEBUG
./run_bridge.sh --broker 192.168.1.100   # if broker is not on localhost

Prerequisites:

  • mosquitto broker running: sudo systemctl start mosquitto
  • ReachyMini daemon running (starts with the robot)

Quick Start

Send a smooth head movement:

mosquitto_pub -t reachy/cmd/goto -m '{"client_id":"test","head":{"pitch":15,"roll":0,"yaw":0},"duration":1.5}'

Watch all feedback:

mosquitto_sub -t 'reachy/state/#' -v

Play an emotion:

mosquitto_pub -t reachy/cmd/emotion -m '{"client_id":"test","name":"happy1"}'

MQTT Topics Reference

Command Topics (publish to these)

reachy/cmd/goto — Smooth motion

Move head, antennas, and/or body with smooth interpolation. This command is queued — it waits for the previous movement to finish.

{
  "client_id": "arduino_1",
  "head": { "pitch": 15.0, "roll": 0.0, "yaw": -30.0 },
  "antennas": { "right": 20.0, "left": -20.0 },
  "body_yaw": 10.0,
  "duration": 1.5,
  "method": "minjerk"
}
  • All fields optional except client_id (must include at least one of head, antennas, body_yaw)
  • All angles in degrees
  • duration: seconds (clamped to 0.1–30.0, default 1.0)
  • method: minjerk (default), linear, ease_in_out, cartoon

reachy/cmd/set — Real-time control

Set target immediately without waiting. Use at 10Hz+ for reactive/tracking control. Bypasses the queue (last writer wins).

{
  "client_id": "arduino_1",
  "head": { "pitch": 10.0, "roll": 5.0, "yaw": 0.0 },
  "antennas": { "right": 0.0, "left": 0.0 }
}

Same fields as goto, no duration or method.

reachy/cmd/behavior — Preset actions

{ "client_id": "arduino_1", "action": "wake_up" }

Valid actions:

  • wake_up — move to init pose, play sound
  • sleep — move to sleep pose, play sound
  • cancel — cancel current movement immediately

reachy/cmd/motors — Motor control

{ "client_id": "arduino_1", "action": "enable" }

Valid actions:

  • enable — motors powered, normal control
  • disable — motors unpowered (robot goes limp)
  • gravity_comp — motors counteract gravity passively

reachy/cmd/emotion — Play an emotion or dance

{ "client_id": "arduino_1", "name": "happy1" }

For dances, specify the dataset:

{ "client_id": "arduino_1", "name": "simple_nod", "dataset": "pollen-robotics/reachy-mini-dances-library" }

State Topics (subscribe to these)

reachy/state/joints — Published at 10 Hz

Current joint positions, all in degrees:

{
  "head": { "pitch": 12.3, "roll": -4.1, "yaw": 20.0 },
  "body_yaw": 10.5,
  "antennas": { "right": 15.0, "left": -10.0 },
  "ts": 1711123456.789
}

reachy/state/status — Published at 1 Hz

{
  "motor_mode": "enabled",
  "queue_depth": 2,
  "ts": 1711123456.789
}

motor_mode values: enabled, disabled, gravity_compensation

reachy/state/ack — Published per command

Every command you send gets an acknowledgement:

{
  "client_id": "arduino_1",
  "topic": "reachy/cmd/goto",
  "status": "accepted",
  "reason": ""
}

status values:

  • accepted — command queued or executed
  • rejected — client's queue is full (reason: "queue_full")
  • error — bad payload or unknown action (see reason)

Safety Limits

The bridge automatically clamps all values to safe ranges. You don't need to worry about breaking the robot — out-of-range values are silently adjusted.

Joint Safe Range
Head pitch ±40°
Head roll ±40°
Head yaw ±180°
Body yaw ±160°
Antennas ±180°

Arduino Example (pseudocode)

#include <ArduinoJson.h>
#include <PubSubClient.h>

// Subscribe to joint state
client.subscribe("reachy/state/joints");
client.subscribe("reachy/state/ack");

// Send a goto command
void sendHeadGoto(float pitch, float roll, float yaw, float duration) {
  StaticJsonDocument<256> doc;
  doc["client_id"] = "arduino_1";
  doc["duration"] = duration;
  JsonObject head = doc.createNestedObject("head");
  head["pitch"] = pitch;
  head["roll"] = roll;
  head["yaw"] = yaw;
  char buf[256];
  serializeJson(doc, buf);
  client.publish("reachy/cmd/goto", buf);
}

// In loop(): read reachy/state/joints to get current position
void callback(char* topic, byte* payload, unsigned int length) {
  if (strcmp(topic, "reachy/state/joints") == 0) {
    StaticJsonDocument<512> doc;
    deserializeJson(doc, payload, length);
    float pitch = doc["head"]["pitch"];
    float right_antenna = doc["antennas"]["right"];
    // ... use these values
  }
}

Available Emotions

Topic: reachy/cmd/emotion, field "name", default dataset pollen-robotics/reachy-mini-emotions-library

amazed1       anxiety1      attentive1    attentive2    boredom1
boredom2      calming1      cheerful1     come1         confused1
contempt1     curious1      dance1        dance2        dance3
disgusted1    displeased1   displeased2   downcast1     dying1
electric1     enthusiastic1 enthusiastic2 exhausted1    fear1
frustrated1   furious1      go_away1      grateful1     helpful1
helpful2      impatient1    impatient2    indifferent1  inquiring1
inquiring2    inquiring3    irritated1    irritated2    laughing1
laughing2     lonely1       lost1         loving1       no1
no_excited1   no_sad1       oops1         oops2         proud1
proud2        proud3        rage1         relief1       relief2
reprimand1    reprimand2    reprimand3    resigned1     sad1
sad2          scared1       serenity1     shy1          sleep1
success1      success2      surprised1    surprised2    thoughtful1
thoughtful2   tired1        uncertain1    uncomfortable1 understanding1
understanding2 welcoming1   welcoming2    yes1          yes_sad1

Available Dances

Topic: reachy/cmd/emotion, field "name", set "dataset": "pollen-robotics/reachy-mini-dances-library"

chicken_peck        chin_lead           dizzy_spin
grid_snap           groovy_sway_and_roll head_tilt_roll
interwoven_spirals  jackson_square      neck_recoil
pendulum_swing      polyrhythm_combo    sharp_side_tilt
side_glance_flick   side_peekaboo       side_to_side_sway
simple_nod          stumble_and_recover uh_huh_tilt
yeah_nod

Multi-Arduino Coordination

The bridge uses a per-client FIFO queue with max 2 pending commands per Arduino, executed round-robin. This means:

  • Every Arduino gets a fair share of robot time
  • If your queue is full, you'll get a rejected ack — slow down or check your ack handler
  • cmd/set bypasses the queue entirely — use it for real-time loops

With 8 Arduinos sending goto commands simultaneously, the robot will execute them one at a time in round-robin order. Expect ~0.5–2s latency depending on movement durations.


Advanced Topics

These features are planned for a future phase:

  • Token system — exclusive control windows (e.g. 7s per Arduino)
  • Swarm patterns — blended averaged control from all Arduinos
  • IMU feedback — accelerometer/gyroscope data on reachy/state/imu
  • Recording/playback — record a sequence and replay it

About

Repo for the UnoQWorshop, hsoting a ReachyMini on a SeeedStudio mision controller (raspberrypi) exposed locally to an MQTT server. The UnoQ can trigger actions via MQTT to move the Reachy mini

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages