5#include "ODriveFlexCAN.hpp"
23template <CAN_DEV_TABLE ODRIVE_CAN0, CAN_DEV_TABLE ODRIVE_CAN1>
39 FlexCAN_T4<CAN2, RX_SIZE_256, TX_SIZE_256> &
odrive_can0,
40 FlexCAN_T4<CAN3, RX_SIZE_256, TX_SIZE_256> &
odrive_can1,
94 end_eff_pos_0_tx, end_eff_pos_1_tx};
122 odrive0_heartbeat_active_tx,
123 encoder0_active_tx, motor0_active_tx, odrive1_heartbeat_active_tx,
124 encoder1_active_tx, motor1_active_tx, mirror_system_active_tx, system_state_tx};
136 { handleHeartbeat(); },
137 odrive0_heartbeat_active_rx, encoder0_active_rx, motor0_active_rx, odrive1_heartbeat_active_rx,
138 encoder1_active_rx, motor1_active_rx, mirror_system_active_rx, system_state_rx};
175 ODRIVE_HEARTBEAT_TIMEOUT;
178 ODRIVE_HEARTBEAT_TIMEOUT;
185 template <
typename T>
188 Serial.println(
"Waiting for ODrive" + String(odrv_ctrl.odrv_user_data_.node_id) +
"...");
189 while (!odrv_ctrl.odrv_user_data_.received_heartbeat)
193 Serial.println(
"Waiting for ODrive" + String(odrv_ctrl.odrv_user_data_.node_id) +
"...");
197 Serial.println(
"Found ODrive");
203 template <
typename T>
206 Serial.println(
"Enabling closed loop control...");
207 while (odrv_ctrl.odrv_user_data_.last_heartbeat.Axis_State !=
208 ODriveAxisState::AXIS_STATE_CLOSED_LOOP_CONTROL)
212 odrv_ctrl.odrv_.setState(ODriveAxisState::AXIS_STATE_CLOSED_LOOP_CONTROL);
213 for (
int i = 0; i < 15; ++i)
219 Serial.println(
"ODrive running!");
260 uint32_t last_received_time;
263 void handleHeartbeat()
Comms Controller class for managing Canlines.
MakeSignedCANSignal(float, 0, 32, 0.0001, 0) end_eff_vel_0_rx
OdriveController< CAN3 > & odrv1_
Address of second odrive.
MakeUnsignedCANSignal(bool, 4, 1, 1, 0) odrive0_heartbeat_active_tx
MakeUnsignedCANSignal(bool, 9, 1, 1, 0) motor1_active_rx
ODriveUserData & get_odrv1_data()
Get the odrv1 user data.
MakeUnsignedCANSignal(bool, 5, 1, 1, 0) encoder0_active_rx
FlexCAN_T4< CAN3, RX_SIZE_256, TX_SIZE_256 > & odrive_can1_
Canline for second odrive.
ODriveCAN & get_odrv0()
Get odrv0.
bool comms_timeout()
Communication timeout on either Teensy or ODrives.
CommsController()=default
MakeSignedCANSignal(float, 32, 32, 0.0001, 0) end_eff_vel_1_rx
MakeUnsignedCANSignal(bool, 8, 1, 1, 0) encoder1_active_rx
MakeUnsignedCANSignal(bool, 5, 1, 1, 0) encoder0_active_tx
MakeUnsignedCANSignal(bool, 10, 1, 1, 0) mirror_system_active_tx
MakeUnsignedCANSignal(ControllerState, 0, 4, 1, 0) system_state_tx
CANTXMessage< 2 > tx_end_eff_vel_message
End effectors velocities to send to the mirror Teensy.
MakeSignedCANSignal(float, 32, 32, 0.0001, 0) end_eff_pos_1_rx
CANTXMessage< 8 > tx_heartbeat_message
Values to send to the ODrive.
CommsController(VirtualTimerGroup &timer_group, FlexCAN_T4< CAN2, RX_SIZE_256, TX_SIZE_256 > &odrive_can0, FlexCAN_T4< CAN3, RX_SIZE_256, TX_SIZE_256 > &odrive_can1, OdriveController< CAN2 > &odrv0, OdriveController< CAN3 > &odrv1, _MB_ptr F, ICAN &teensy_can)
Construct the comms controller.
FlexCAN_T4< CAN2, RX_SIZE_256, TX_SIZE_256 > & odrive_can0_
Canline for first odrive.
ODriveCAN & get_odrv1()
Get odrv1.
MakeSignedCANSignal(float, 32, 32, 0.0001, 0) end_eff_pos_1_tx
MakeUnsignedCANSignal(bool, 6, 1, 1, 0) motor0_active_tx
ODriveUserData & get_odrv0_data()
Get the odrv0 user data.
bool teensy_heartbeat_timeout
MakeUnsignedCANSignal(bool, 4, 1, 1, 0) odrive0_heartbeat_active_rx
CANTXMessage< 2 > tx_end_eff_pos_message
End effectors positions to send to the mirror Teensy.
MakeUnsignedCANSignal(ControllerState, 0, 4, 1, 0) system_state_rx
void startup_odrive(T odrv_ctrl)
Enable closed loop control on odrive.
bool Initialize()
Initialize the ODrives and the Teensy CAN, must be called in setup procedure.
MakeUnsignedCANSignal(bool, 9, 1, 1, 0) motor1_active_tx
MakeUnsignedCANSignal(bool, 8, 1, 1, 0) encoder1_active_tx
MakeSignedCANSignal(float, 0, 32, 0.0001, 0) end_eff_pos_0_tx
void find_odrive(T odrv_ctrl)
Receive hearbeats on odrives.
ICAN & teensy_can
: Teensy Canline
MakeUnsignedCANSignal(bool, 7, 1, 1, 0) odrive1_heartbeat_active_rx
MakeSignedCANSignal(float, 0, 32, 0.0001, 0) end_eff_pos_0_rx
OdriveController< CAN2 > & odrv0_
Address of first odrive.
MakeSignedCANSignal(float, 32, 32, 0.0001, 0) end_eff_vel_1_tx
MakeUnsignedCANSignal(bool, 10, 1, 1, 0) mirror_system_active_rx
MakeSignedCANSignal(float, 0, 32, 0.0001, 0) end_eff_vel_0_tx
CANRXMessage< 2 > rx_end_eff_vel_message
End effectors velocities received by the mirror Teensy.
CANRXMessage< 2 > rx_end_eff_pos_message
End effectors positions received by the mirror Teensy.
CANRXMessage< 8 > rx_heartbeat_message
Values received by the ODrive.
void Tick()
Tick Odrive CAN buses and checks timeouts.
MakeUnsignedCANSignal(bool, 6, 1, 1, 0) motor0_active_rx
VirtualTimerGroup & timer_group
Address of timer group that the comms rely on.
MakeUnsignedCANSignal(bool, 7, 1, 1, 0) odrive1_heartbeat_active_tx
Class that abstracts operations with the ODrive/.
ODriveUserData & odrv_user_data_
struct to store user data in
bool startup_odrive_checks()
Set parameters and set the motor to torque control.
ODriveCAN odrv_
Odrive object to control.
ControllerState
The state of the system.
uint32_t last_received_time
OdriveController< CAN3 > odrv1
: Odrive for second joint
FlexCAN_T4< CAN2, RX_SIZE_256, TX_SIZE_256 > odrive_can0
FlexCAN_T4< CAN3, RX_SIZE_256, TX_SIZE_256 > odrive_can1
OdriveController< CAN2 > odrv0
: Odrive for first joint
: The Struct to contain feedback from the ODrive
uint32_t last_heartbeat_time