Skip to content

Commit 9a0868b

Browse files
committed
autosync
1 parent ce1eea2 commit 9a0868b

File tree

11 files changed

+1659
-0
lines changed

11 files changed

+1659
-0
lines changed

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
2+
# Doxygen
3+
/src/xml
4+
5+
# PlatformIO
6+
/.pio
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# See https://github.com/Arduino-CI/arduino_ci/blob/master/REFERENCE.md
2+
3+
compile:
4+
platforms:
5+
- uno_minima_r4
6+
7+
packages:
8+
teensy:teensy:
9+
url: https://www.pjrc.com/teensy/package_teensy_index.json
10+
arduino:renesas_uno:
11+
url: https://downloads.arduino.cc/packages/package_index.json
12+
13+
platforms:
14+
uno_minima_r4:
15+
board: arduino:renesas_uno:minima
16+
package: arduino:renesas_uno
17+
gcc:
18+
features:
19+
defines:
20+
- IS_ARDUINO_BUILTIN
21+
warnings:
22+
flags:
23+
teensy41:
24+
board: teensy:teensy:teensy41
25+
package: teensy:teensy
26+
gcc:
27+
features:
28+
defines:
29+
- __IMXRT1062__
30+
- ARDUINO_ARCH_TEENSY
31+
- TEENSY41
32+
- IS_TEENSY_BUILTIN
33+
warnings:
34+
flags:
Lines changed: 263 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,263 @@
1+
2+
#include <Arduino.h>
3+
#include "ODriveCAN.hpp"
4+
5+
6+
/* Configuration of example sketch -------------------------------------------*/
7+
8+
// CAN bus baudrate. Make sure this matches for every device on the bus
9+
#define CAN_BAUDRATE 250000
10+
11+
// ODrive node_id for odrv0
12+
#define ODRV0_NODE_ID 0
13+
14+
//========================================================================
15+
// required ODrive Configuration:
16+
// odrv.can.config.baud_rate = <CAN_BAUDRATE>
17+
// odrv.axis0.config.can.node_id = <ODRV{i}_NODE_ID>
18+
// odrv.axis0.config.can.encoder_msg_rate_ms != 0, suggest 25
19+
// odrv.axis0.config.can.heartbeat_msg_rate_ms != 0, suggest 250
20+
//========================================================================
21+
22+
// Uncomment below the line that corresponds to your hardware.
23+
// See also "Board-specific settings" to adapt the details for your hardware setup.
24+
25+
// #define IS_TEENSY_BUILTIN // Teensy boards with built-in CAN interface (e.g. Teensy 4.1). See below to select which interface to use.
26+
// #define IS_ARDUINO_BUILTIN // Arduino boards with built-in CAN interface (e.g. Arduino Uno R4 Minima)
27+
// #define IS_MCP2515 // Any board with external MCP2515 based extension module. See below to configure the module.
28+
29+
30+
/* Board-specific includes ---------------------------------------------------*/
31+
32+
#if defined(IS_TEENSY_BUILTIN) + defined(IS_ARDUINO_BUILTIN) + defined(IS_MCP2515) != 1
33+
#warning "Select exactly one hardware option at the top of this file."
34+
35+
#if CAN_HOWMANY > 0 || CANFD_HOWMANY > 0
36+
#define IS_ARDUINO_BUILTIN
37+
#warning "guessing that this uses HardwareCAN"
38+
#else
39+
#error "cannot guess hardware version"
40+
#endif
41+
42+
#endif
43+
44+
#ifdef IS_ARDUINO_BUILTIN
45+
// See https://github.com/arduino/ArduinoCore-API/blob/master/api/HardwareCAN.h
46+
// and https://github.com/arduino/ArduinoCore-renesas/tree/main/libraries/Arduino_CAN
47+
48+
#include <Arduino_CAN.h>
49+
#include <ODriveHardwareCAN.hpp>
50+
#endif // IS_ARDUINO_BUILTIN
51+
52+
#ifdef IS_MCP2515
53+
// See https://github.com/sandeepmistry/arduino-CAN/
54+
#include "MCP2515.h"
55+
#include "ODriveMCPCAN.hpp"
56+
#endif // IS_MCP2515
57+
58+
#ifdef IS_TEENSY_BUILTIN
59+
// See https://github.com/tonton81/FlexCAN_T4
60+
// clone https://github.com/tonton81/FlexCAN_T4.git into /src
61+
#include <FlexCAN_T4.h>
62+
#include "ODriveFlexCAN.hpp"
63+
struct ODriveStatus; // hack to prevent teensy compile error
64+
#endif // IS_TEENSY_BUILTIN
65+
66+
67+
68+
69+
/* Board-specific settings ---------------------------------------------------*/
70+
71+
72+
/* Teensy */
73+
74+
#ifdef IS_TEENSY_BUILTIN
75+
76+
FlexCAN_T4<CAN1, RX_SIZE_256, TX_SIZE_16> can_intf;
77+
78+
bool setupCan() {
79+
can_intf.begin();
80+
can_intf.setBaudRate(CAN_BAUDRATE);
81+
can_intf.setMaxMB(16);
82+
can_intf.enableFIFO();
83+
can_intf.enableFIFOInterrupt();
84+
can_intf.onReceive(onCanMessage);
85+
return true;
86+
}
87+
88+
#endif // IS_TEENSY_BUILTIN
89+
90+
91+
/* MCP2515-based extension modules -*/
92+
93+
#ifdef IS_MCP2515
94+
95+
MCP2515Class& can_intf = CAN;
96+
97+
// chip select pin used for the MCP2515
98+
#define MCP2515_CS 10
99+
100+
// interrupt pin used for the MCP2515
101+
// NOTE: not all Arduino pins are interruptable, check the documentation for your board!
102+
#define MCP2515_INT 2
103+
104+
// freqeuncy of the crystal oscillator on the MCP2515 breakout board.
105+
// common values are: 16 MHz, 12 MHz, 8 MHz
106+
#define MCP2515_CLK_HZ 8000000
107+
108+
109+
static inline void receiveCallback(int packet_size) {
110+
if (packet_size > 8) {
111+
return; // not supported
112+
}
113+
CanMsg msg = {.id = (unsigned int)CAN.packetId(), .len = (uint8_t)packet_size};
114+
CAN.readBytes(msg.buffer, packet_size);
115+
onCanMessage(msg);
116+
}
117+
118+
bool setupCan() {
119+
// configure and initialize the CAN bus interface
120+
CAN.setPins(MCP2515_CS, MCP2515_INT);
121+
CAN.setClockFrequency(MCP2515_CLK_HZ);
122+
if (!CAN.begin(CAN_BAUDRATE)) {
123+
return false;
124+
}
125+
126+
CAN.onReceive(receiveCallback);
127+
return true;
128+
}
129+
130+
#endif // IS_MCP2515
131+
132+
133+
/* Arduinos with built-in CAN */
134+
135+
#ifdef IS_ARDUINO_BUILTIN
136+
137+
HardwareCAN& can_intf = CAN;
138+
139+
bool setupCan() {
140+
return can_intf.begin((CanBitRate)CAN_BAUDRATE);
141+
}
142+
143+
#endif
144+
145+
146+
/* Example sketch ------------------------------------------------------------*/
147+
148+
// Instantiate ODrive objects
149+
ODriveCAN odrv0(wrap_can_intf(can_intf), ODRV0_NODE_ID); // Standard CAN message ID
150+
ODriveCAN* odrives[] = {&odrv0}; // Make sure all ODriveCAN instances are accounted for here
151+
152+
struct ODriveUserData {
153+
Heartbeat_msg_t last_heartbeat;
154+
bool received_heartbeat = false;
155+
Get_Encoder_Estimates_msg_t last_feedback;
156+
bool received_feedback = false;
157+
};
158+
159+
ODriveUserData odrv0_user_data;
160+
161+
void onHeartbeat(Heartbeat_msg_t& msg, void* user_data) {
162+
ODriveUserData* odrv_user_data = static_cast<ODriveUserData*>(user_data);
163+
odrv_user_data->last_heartbeat = msg;
164+
odrv_user_data->received_heartbeat = true;
165+
}
166+
167+
void onFeedback(Get_Encoder_Estimates_msg_t& msg, void* user_data) {
168+
ODriveUserData* odrv_user_data = static_cast<ODriveUserData*>(user_data);
169+
odrv_user_data->last_feedback = msg;
170+
odrv_user_data->received_feedback = true;
171+
}
172+
173+
void onCanMessage(const CanMsg& msg) {
174+
for (auto odrive: odrives) {
175+
onReceive(msg, *odrive);
176+
}
177+
}
178+
179+
void setup() {
180+
Serial.begin(115200);
181+
182+
// Wait for up to 3 seconds for the serial port to be opened on the PC side.
183+
// If no PC connects, continue anyway.
184+
for (int i = 0; i < 30 && !Serial; ++i) {
185+
delay(100);
186+
}
187+
delay(200);
188+
189+
190+
Serial.print("Starting ODriveCAN demo");
191+
192+
// Set ODriveCAN callbacks for the encoder feedback and the axis status
193+
odrv0.onFeedback(onFeedback, &odrv0_user_data);
194+
odrv0.onStatus(onHeartbeat, &odrv0_user_data);
195+
196+
// Configure and initialize the CAN bus interface. This function is
197+
if (!setupCan()) {
198+
Serial.println("CAN failed to initialize: reset required");
199+
while (true); // spin indefinitely
200+
}
201+
202+
Serial.println("Waiting for ODrive...");
203+
while (!odrv0_user_data.received_heartbeat) {
204+
pumpEvents(can_intf);
205+
delay(100);
206+
}
207+
208+
Serial.println("found ODrive");
209+
210+
// request bus voltage and current (1sec timeout)
211+
Serial.println("attempting to read bus voltage and current");
212+
Get_Bus_Voltage_Current_msg_t vbus;
213+
if (!odrv0.request(vbus, 1)) {
214+
Serial.println("vbus request failed!");
215+
while (true); // spin indefinitely
216+
}
217+
218+
Serial.print("DC voltage [V]: ");
219+
Serial.println(vbus.Bus_Voltage);
220+
Serial.print("DC current [A]: ");
221+
Serial.println(vbus.Bus_Current);
222+
223+
224+
// make sure odrv0 is configured for trajectory commands
225+
Serial.println("Setting trajectory mode...");
226+
if (!odrv0.setControllerMode(ODriveControlMode::CONTROL_MODE_POSITION_CONTROL, ODriveInputMode::INPUT_MODE_TRAP_TRAJ)) {
227+
Serial.println("failed to set Controller Mode");
228+
while (true); // spin indefinitely
229+
}
230+
231+
Serial.println("Enabling closed loop control...");
232+
while (odrv0_user_data.last_heartbeat.Axis_State != ODriveAxisState::AXIS_STATE_CLOSED_LOOP_CONTROL) {
233+
odrv0.clearErrors();
234+
odrv0.setState(ODriveAxisState::AXIS_STATE_CLOSED_LOOP_CONTROL);
235+
delay(10); // small delay to avoid spamming the CAN bus
236+
pumpEvents(can_intf);
237+
}
238+
239+
Serial.println("ODrive running!");
240+
}
241+
242+
bool fwd_rev = false;
243+
244+
void loop() {
245+
pumpEvents(can_intf);
246+
247+
// print position and velocity for Serial Plotter
248+
if (odrv0_user_data.received_feedback) {
249+
odrv0_user_data.received_feedback = false;
250+
Serial.print("odrv0-pos:");
251+
Serial.print(odrv0_user_data.last_feedback.Pos_Estimate);
252+
Serial.print(",");
253+
Serial.print("odrv0-vel:");
254+
Serial.println(odrv0_user_data.last_feedback.Vel_Estimate);
255+
}
256+
257+
if (odrv0_user_data.last_heartbeat.Trajectory_Done_Flag) {
258+
// If trajectory is done, set new target pos for the trajectory planner
259+
float target_pos = fwd_rev ? 5.0f : -5.0f;
260+
fwd_rev = !fwd_rev;
261+
if (!odrv0.trapezoidalMove(target_pos)) Serial.println("trapezoidalMove command failed!");
262+
}
263+
}

platformio.ini

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
; PlatformIO Project Configuration File
2+
;
3+
; Build options: build flags, source filter
4+
; Upload options: custom upload port, speed and extra flags
5+
; Library options: dependencies, extra library storages
6+
; Advanced options: extra scripting
7+
;
8+
; Please visit documentation for the other options and examples
9+
; https://docs.platformio.org/page/projectconf.html
10+
11+
[platformio]
12+
src_dir = examples/TrapTrajCAN
13+
lib_dir = .
14+
15+
[env:teensy41]
16+
platform = teensy
17+
board = teensy41
18+
framework = arduino
19+
build_flags = -DIS_TEENSY_BUILTIN
20+
21+
[env:uno_r4_minima]
22+
platform = renesas-ra
23+
board = uno_r4_minima
24+
framework = arduino
25+
build_flags = -DIS_ARDUINO_BUILTIN
26+
27+
[env:uno]
28+
platform = atmelavr
29+
board = uno
30+
framework = arduino
31+
build_flags = -DIS_MCP2515
32+
lib_deps =
33+
https://github.com/sandeepmistry/arduino-CAN.git

0 commit comments

Comments
 (0)