Skip to content

NT-X integration ​

Status: catalog, simulation and the serial transport are verified inside the NT-X harness environment (make ntx-smoke). Opening the physical robot from an NT-X session needs one NT-X core change (below).

packages/strido-ntx is an NT-X extension. Installed into the NT-X environment it contributes:

Entry pointContributes
ntx.assets → strido_ntxrobots/strido.yaml (RobotSpec), robots/models/strido.xml + meshes (MJCF), skills/strido-stand.yaml
ntx.adapters → strido_ntx.plugin:registerrobot adapter strido-serial → StridoSerialPort
ntx-extension.yamlmanifest for ntx ext info/doctor strido

Install into NT-X ​

bash
cd ../../ntx-harness
uv pip install -e ../workspace/robot/packages/strido-core -e ../workspace/robot/packages/strido-ntx
uv run ntx ext doctor strido
uv run ntx robots show strido

make ntx-smoke runs the same checks without touching the NT-X virtualenv (uv run --project ntx-harness --with-editable …): the robot loads from the catalog, compiles into an NT-X MuJoCo world and stands for 2 s, the adapter is registered, and the serial port drives a protocol-level fake MCU (command → state → protective stop → close).

Robot spec ​

Generated by python -m strido_ntx.build_assets from the CAD-derived MJCF (make models runs it; make drift checks it):

  • joints in MCU order FL, FR, RL, RR × (hip, thigh, calf), limits from the collision sweep, defaults = 170 mm stand pose;
  • SPT5435LV limits: 3.43 N·m effort, 7.48 rad/s velocity; PD gains from the MuJoCo servo model;
  • feet FL_foot … bodies at the foot centres; hardware_status: unverified until a robot is qualified.

RobotPort semantics (StridoSerialPort) ​

NT-X expectsStrido provides
read_state().q, dq, tauq = the angle the MCU applies after its clamps (hobby servos report nothing); dq zeros; tau empty
base pose / velocityorientation + body rates from the IMU; position and linear velocity not measured → has_odometry = False. A state with imu_ok cleared latches the protective stop and raises ImuUnavailableError (fail closed)
apply(JointCommand)position target only. Positive kp/kd run as the servo's fixed stiffness and tau_ff (the gravity feed-forward of pd-pose) is dropped; a non-zero dq or kp <= 0 is rejected; non-finite targets latch a protective stop
hold()re-sends the last target (MCU watchdog holds 200 ms, relaxes after 2 s)
protective_stop()latched MCU e-stop: PCA9685 OE high, every servo pulse off. Servos go limp (no damping)
release(), close()clear the e-stop; stop and free the serial device
freshnessthe input buffer is flushed on open and drained on every poll (newest frame wins); TimeoutError when no state frame arrives within 0.2 s

Odometry gate. NT-X sessions refuse non-gantry skills on a port without odometry (ntx.runtime.session._check_port_support). strido-stand is a free-standing skill, so on hardware it runs only after a base estimator exists, or as a gantry variant with the body on a stand and the legs free. Simulation sessions are unaffected (the MuJoCo port measures the base).

What NT-X needs to change for hardware sessions ​

NT-X opens hardware through ntx.deploy.open_robot_port, which always builds the Unitree SDK2 port, and TargetSpec.transport.kind only accepts unitree-sdk2. To run Strido live from a session, NT-X should dispatch hardware through its adapter registry:

  1. allow transport.kind values that name a registered robot adapter (e.g. strido-serial);
  2. in open_robot_port, registry.create("robot", target.transport.kind, spec=robot, device=…);
  3. add a target config/targets/strido-desk.yaml with the qualification gates (identity, e-stop, shadow) for a built robot;
  4. provide a base pose estimate (IMU + leg kinematics) or a gantry variant of strido-stand for the first hardware sessions.

This change belongs to the NT-X repository and is tracked in TODO; nothing in this repository edits NT-X.

Training in NT-X ​

The NT-X locomotion-velocity template trains any catalog quadruped: uv run ntx train run --template locomotion-velocity --set spec.robot_id=strido. Policies trained there use NT-X's observation layout; the Strido ROS 2 policy_node runs policies from strido_sim.rl.train (feedback-free observation). Bridging the two runtimes is open work.

MIT licence. Mechanical design derived from Yertle by Jerome Graves. CAD, simulation and native tests are not hardware evidence — see Verification.