|
| 1 | +#pragma once |
| 2 | + |
| 3 | +#include <cmath> // NAN |
| 4 | + |
| 5 | +// ============================================================================= |
| 6 | +// Arm Command Types (arm_commands.h) |
| 7 | +// ============================================================================= |
| 8 | +// |
| 9 | +// This file defines what commands the ROS layer can send to the driver and |
| 10 | +// how those commands are stored internally while they wait to be sent on the |
| 11 | +// CAN bus. |
| 12 | +// |
| 13 | +// Flow: |
| 14 | +// /arm/command topic → commandCallback() → pending_cmds_[] |
| 15 | +// → (next poll tick) → active_cmds_[] |
| 16 | +// → CAN frame via moteus_protocol.h |
| 17 | +// |
| 18 | +// Why two arrays (pending / active)? |
| 19 | +// The moteus controller has a watchdog: if it stops receiving valid CAN |
| 20 | +// frames it will fault (fault code 32 = timeout). active_cmds_ is |
| 21 | +// re-sent every poll cycle so the watchdog never fires, even if the ROS |
| 22 | +// topic goes quiet. pending_cmds_ just holds the latest user intent |
| 23 | +// until the next poll tick picks it up. |
| 24 | +// ============================================================================= |
| 25 | + |
| 26 | + |
| 27 | +// ----------------------------------------------------------------------------- |
| 28 | +// Command codes — carried in rover_msgs::msg::ArmCommand::cmd_type |
| 29 | +// ----------------------------------------------------------------------------- |
| 30 | + |
| 31 | +// Stop all motors immediately. |
| 32 | +// - Motor enters kStopped mode → no torque, no position hold (goes limp). |
| 33 | +// - Always accepted, even when a fault is active. |
| 34 | +// - Clears fault-blocking so motion commands can resume afterwards. |
| 35 | +constexpr char CMD_STOP = 'S'; |
| 36 | + |
| 37 | +// Absolute position command. |
| 38 | +// positions[] = target output-shaft revolutions for each motor (NaN = skip that motor) |
| 39 | +// velocities[] = optional velocity feed-forward in rev/s (NaN = use motion profile) |
| 40 | +// Blocked if the target motor has an active fault — send CMD_STOP first. |
| 41 | +constexpr char CMD_ABS_POS = 'P'; |
| 42 | + |
| 43 | +// Velocity command (jog mode — hold the button to move). |
| 44 | +// velocities[] = target output-shaft rev/s for each motor (NaN = skip that motor) |
| 45 | +// A velocity of exactly 0.0 is treated as CMD_STOP for that motor |
| 46 | +// (motor goes limp, not hold-position), matching the jog-button release behaviour. |
| 47 | +constexpr char CMD_ABS_VEL = 'V'; |
| 48 | + |
| 49 | +// Zero (re-home) command — equivalent to "d exact 0" in tview. |
| 50 | +// Resets the position counter to 0.0 at the current physical position. |
| 51 | +// The motor does NOT move — only the position reference is updated. |
| 52 | +// Use this to establish a new zero point after manually positioning the arm. |
| 53 | +// positions[] used as a flag: any non-NaN entry means "zero that motor". |
| 54 | +constexpr char CMD_ZERO = 'Z'; |
| 55 | + |
| 56 | + |
| 57 | +// ----------------------------------------------------------------------------- |
| 58 | +// Internal command state — one slot per motor |
| 59 | +// ----------------------------------------------------------------------------- |
| 60 | + |
| 61 | +// Represents one pending or active motion instruction for a single motor. |
| 62 | +// Stored in MoteusDriverNode::pending_cmds_[] and active_cmds_[]. |
| 63 | +struct MotorCommand { |
| 64 | + bool active = false; // true → there is something to send this cycle |
| 65 | + bool is_stop = false; // true → send MakeStop; overrides everything |
| 66 | + bool is_zero = false; // true → send "d exact 0" (re-home in place); one-shot |
| 67 | + double position = 0.0; // output-shaft revolutions (NaN = no position target) |
| 68 | + double velocity = 0.0; // output-shaft rev/s (NaN = use motion profile) |
| 69 | + double max_torque = NAN; // N·m output-shaft cap (NaN = firmware default) |
| 70 | +}; |
0 commit comments