TrickFire Robotics

Architecture

Repo layout and what each ROS 2 package does.

Repo layout

plaintext
viator/
├── src/                  # ROS 2 workspace (colcon)
│   ├── arm/              # Arm control node
│   ├── camera/           # Camera streaming node
│   ├── can_moteus/       # Moteus motor controller driver
│   ├── can_rmdx8/        # RMD-X8 motor controller driver
│   ├── custom_interfaces/# Shared .srv/.msg definitions
│   ├── drivebase/        # Drivebase (wheel) control node
│   ├── heartbeat/        # Connection watchdog / e-stop
│   ├── lib/               # Shared Python library (not a standalone node)
│   ├── mission_control_updater/ # Publishes robot state to mission control
│   ├── viator_launch/    # Top-level launch file
│   └── vision_opencv/    # Git submodule (ros-perception/vision_opencv)
├── scripts/              # Build/launch/deploy shell scripts (see Makefile)
├── .devcontainer/        # Dockerfile + bashrc for the dev container
└── Makefile              # `make build` / `make launch` / etc.

src/ is a standard ROS 2 (colcon) workspace. Every package here is ament_python except custom_interfaces, which is ament_cmake (it only generates message/service headers via rosidl_generate_interfaces, no compiled node code).

lib/ — shared library

Not a ROS node itself; every node package imports from here.

FilePurpose
lib/configs.pyStatic motor configuration (CAN IDs, motor type, gear ratios) shared across the whole robot.
lib/interface/robot_interface.pyRobotInterface — the utility class nodes use to command motors (converts between physical units and raw motor commands, publishes over the CAN bridges).
lib/interface/robot_info.pyRobotInfo — the read-side counterpart: subscribes to motor state topics and exposes the current state of every motor on the robot.
lib/motor_state/Typed state objects for each motor backend (CANMotorState, MoteusMotorState, RMDX8MotorState).
lib/color_codes.py, lib/json_msg.pySmall logging/serialization helpers.

Motor drivers

Two independent CAN motor controller backends, both bridging to the shared lib/motor_state types:

can_moteus

Drives mjbots moteus controllers over a CANFD-USB adapter.

mjbots moteus · ros_moteus_bridge.py, moteus_thread_manager.py, moteus_motor.py

can_rmdx8

Drives MyActuator RMD-X8 controllers, exposed to Python via pybind11.

myactuator_rmd · rmdx8_motor_manager.py, rmdx8_motor.py (built from source in the Dockerfile)

Robot-facing nodes

NodeDescription
drivebaseSubscribes to left/right drive commands and forwards them to the wheel motors via RobotInterface.
armArm control; supports per-motor velocity/position control today (individual_control_vel.py), with inverse kinematics stubbed out as a future ArmModeEnum mode. Mode is switched at runtime via the custom_interfaces/srv/ArmMode service.
cameraroscamera node (camera/roscamera.py) enumerates connected USB cameras and publishes compressed image streams over sensor_msgs/CompressedImage.
heartbeatConnection watchdog: if the base station connection drops, it's responsible for cutting power to the motors as a safety stop.
mission_control_updaterPeriodically collects motor state via RobotInfo, serializes it to JSON (info_to_json_helper.py), and publishes it for the mission control dashboard (delivered over ros-humble-rosbridge-server, installed in the Dockerfile).

custom_interfaces

Shared ROS interface definitions used across packages, e.g. srv/ArmMode.srv (switches the arm's control mode: disabled / individual motor velocity / individual motor position / inverse kinematics).

viator_launch

launch/robot.launch.py is the single entry point that starts every node above together — this is what make launch runs (ros2 launch viator_launch robot.launch.py).

See Launching the Rover for the full build → CAN setup → launch workflow.

vision_opencv

A git submodule pointing at ros-perception/vision_opencv (ros2 branch), providing cv_bridge for OpenCV/ROS image conversion. It's excluded from this repo's own lint/format tooling since it isn't our code.

On this page