@@ -31,6 +31,8 @@ LOG_MODULE_REGISTER(actuate_vesc_can, CONFIG_CEREBRI_ACTUATE_VESC_CAN_LOG_LEVEL)
31
31
#define MY_STACK_SIZE 4096
32
32
#define MY_PRIORITY 4
33
33
34
+ #define CAN_STATUS_ID_BASE 0x00000900
35
+
34
36
#ifndef M_PI
35
37
#define M_PI 3.14159265358979323846
36
38
#endif
@@ -39,46 +41,70 @@ uint32_t g_send_count = 0;
39
41
40
42
extern struct perf_duration control_latency ;
41
43
44
+ static void actuate_vesc_can_rx_callback (const struct device * dev , struct can_frame * frame ,
45
+ void * user_data );
46
+
42
47
typedef enum vesc_can_type_t {
43
48
VESC_CAN_TYPE_NORMALIZED = 0 ,
44
49
VESC_CAN_TYPE_POSITION = 1 ,
45
50
VESC_CAN_TYPE_VELOCITY = 2 ,
46
51
} vesc_can_type_t ;
47
52
48
- typedef struct actuator_vesc_can_t {
53
+ struct actuator_vesc_can {
49
54
const char * label ;
50
55
uint8_t id ;
51
56
uint8_t index ;
52
57
uint8_t pole_pair ;
53
58
uint8_t vesc_id ;
54
59
vesc_can_type_t type ;
55
- } actuator_vesc_can_t ;
60
+ struct can_filter rx_filter ;
61
+ struct context * ctx ;
62
+ double rotation ;
63
+ };
56
64
57
65
struct context {
58
66
synapse_pb_Actuators actuators ;
67
+ synapse_pb_WheelOdometry wheel_odometry ;
59
68
synapse_pb_Status status ;
60
69
struct zros_node node ;
61
70
struct zros_sub sub_actuators , sub_status ;
71
+ struct zros_pub pub_wheel_odometry ;
62
72
struct k_sem running ;
63
73
size_t stack_size ;
64
74
k_thread_stack_t * stack_area ;
65
75
struct k_thread thread_data ;
66
76
uint8_t num_actuators ;
67
- actuator_vesc_can_t * actuator_vesc_cans ;
77
+ struct actuator_vesc_can * actuator_vesc_cans ;
68
78
const struct device * device ;
69
79
bool ready ;
70
80
bool fd ;
71
81
const char * label ;
82
+ uint16_t status_rate ;
83
+ bool enable_pub_wheel_odom ;
72
84
};
73
85
74
86
static int actuate_vesc_can_stop (struct context * ctx )
75
87
{
88
+ int err = 0 ;
89
+ struct can_bus_err_cnt err_cnt ;
90
+ enum can_state state ;
76
91
ctx -> ready = false;
77
- int err = can_stop (ctx -> device );
92
+ err = can_get_state (ctx -> device , & state , & err_cnt );
78
93
if (err != 0 ) {
79
- LOG_ERR ("%s - failed to stop (%d)\n" , ctx -> label , err );
94
+ LOG_ERR ("%s - failed to get CAN controller state (%d)\n" , ctx -> label , err );
95
+ ctx -> ready = false;
80
96
return err ;
81
97
}
98
+
99
+ // make sure stopped
100
+ if (state != CAN_STATE_STOPPED ) {
101
+ err = can_stop (ctx -> device );
102
+ if (err != 0 ) {
103
+ LOG_ERR ("%s - failed to stop (%d)\n" , ctx -> label , err );
104
+ return err ;
105
+ }
106
+ }
107
+
82
108
return err ;
83
109
}
84
110
@@ -88,9 +114,8 @@ static int actuate_vesc_can_init(struct context *ctx)
88
114
zros_node_init (& ctx -> node , "actuate_vesc_can" );
89
115
zros_sub_init (& ctx -> sub_actuators , & ctx -> node , & topic_actuators , & ctx -> actuators , 1000 );
90
116
zros_sub_init (& ctx -> sub_status , & ctx -> node , & topic_status , & ctx -> status , 10 );
91
-
92
- enum can_state state ;
93
- struct can_bus_err_cnt err_cnt ;
117
+ zros_pub_init (& ctx -> pub_wheel_odometry , & ctx -> node , & topic_wheel_odometry ,
118
+ & ctx -> wheel_odometry );
94
119
95
120
if (ctx -> ready ) {
96
121
LOG_ERR ("%s - already initialized" , ctx -> label );
@@ -102,19 +127,12 @@ static int actuate_vesc_can_init(struct context *ctx)
102
127
LOG_ERR ("%s - device not ready\n" , ctx -> label );
103
128
ctx -> ready = false;
104
129
return -1 ;
105
- } // check state
106
- err = can_get_state (ctx -> device , & state , & err_cnt );
107
- if (err != 0 ) {
108
- LOG_ERR ("%s - failed to get CAN controller state (%d)\n" , ctx -> label , err );
109
- ctx -> ready = false;
110
- return err ;
111
130
}
112
131
132
+ actuate_vesc_can_stop (ctx );
133
+
113
134
// set device mode
114
135
if (ctx -> fd ) {
115
- if (state != CAN_STATE_STOPPED ) {
116
- actuate_vesc_can_stop (ctx );
117
- }
118
136
err = can_set_mode (ctx -> device , CAN_MODE_FD );
119
137
if (err != 0 ) {
120
138
LOG_ERR ("%s - set mode FD failed (%d)\n" , ctx -> label , err );
@@ -123,10 +141,23 @@ static int actuate_vesc_can_init(struct context *ctx)
123
141
}
124
142
125
143
// start device
126
- if ((state == CAN_STATE_STOPPED ) || (state == CAN_STATE_BUS_OFF )) {
127
- err = can_start (ctx -> device );
128
- if (err != 0 ) {
129
- LOG_ERR ("%s - start failed\n" , ctx -> label );
144
+ err = can_start (ctx -> device );
145
+ if (err != 0 ) {
146
+ LOG_ERR ("%s - start failed\n" , ctx -> label );
147
+ return err ;
148
+ }
149
+
150
+ // add receive callback
151
+ for (int i = 0 ; i < ctx -> num_actuators ; i ++ ) {
152
+ struct actuator_vesc_can * act = & ctx -> actuator_vesc_cans [i ];
153
+ act -> ctx = ctx ;
154
+ act -> rx_filter .flags = CAN_FILTER_IDE ;
155
+ act -> rx_filter .id = CAN_STATUS_ID_BASE + act -> vesc_id ;
156
+ act -> rx_filter .mask = CAN_EXT_ID_MASK ;
157
+ err = can_add_rx_filter (ctx -> device , actuate_vesc_can_rx_callback , act ,
158
+ & act -> rx_filter );
159
+ if (err < 0 ) {
160
+ LOG_ERR ("%s - callback setup failed (%d)\n" , ctx -> label , err );
130
161
return err ;
131
162
}
132
163
}
@@ -143,32 +174,55 @@ static int actuate_vesc_can_fini(struct context *ctx)
143
174
actuate_vesc_can_stop (ctx );
144
175
zros_sub_fini (& ctx -> sub_actuators );
145
176
zros_sub_fini (& ctx -> sub_status );
177
+ zros_pub_fini (& ctx -> pub_wheel_odometry );
146
178
zros_node_fini (& ctx -> node );
147
179
k_sem_give (& ctx -> running );
148
180
LOG_INF ("fini" );
149
181
return 0 ;
150
182
}
151
183
184
+ static void actuate_vesc_can_rx_callback (const struct device * dev , struct can_frame * frame ,
185
+ void * user_data )
186
+ {
187
+ struct actuator_vesc_can * act = (struct actuator_vesc_can * )user_data ;
188
+ struct context * ctx = act -> ctx ;
189
+ int64_t data = (frame -> data [0 ] << 24 ) + (frame -> data [1 ] << 16 ) + (frame -> data [2 ] << 8 ) +
190
+ frame -> data [3 ];
191
+ act -> rotation += 2 * M_PI * data / (act -> pole_pair * ctx -> status_rate * 60 );
192
+ // LOG_INF("Data: %ld", data);
193
+ // LOG_INF("Angular: %f", act->rotation);
194
+ if (act -> id == ctx -> actuator_vesc_cans [0 ].id ) {
195
+ double mean_rotation = 0 ;
196
+ for (int i = 0 ; i < ctx -> num_actuators ; i ++ ) {
197
+ mean_rotation += ctx -> actuator_vesc_cans [i ].rotation ;
198
+ }
199
+ mean_rotation /= ctx -> num_actuators ;
200
+ ctx -> wheel_odometry .has_stamp = true;
201
+ stamp_msg (& ctx -> wheel_odometry .stamp , k_uptime_ticks ());
202
+ ctx -> wheel_odometry .rotation = mean_rotation ;
203
+ }
204
+ }
205
+
152
206
static void actuate_vesc_can_update (struct context * ctx )
153
207
{
154
208
bool armed = ctx -> status .arming == synapse_pb_Status_Arming_ARMING_ARMED ;
155
209
int err = 0 ;
156
210
157
211
for (int i = 0 ; i < ctx -> num_actuators ; i ++ ) {
158
- actuator_vesc_can_t * vesc_can = & ctx -> actuator_vesc_cans [i ];
212
+ struct actuator_vesc_can * act = & ctx -> actuator_vesc_cans [i ];
159
213
160
214
struct can_frame frame = {
161
215
.dlc = can_bytes_to_dlc (4 ),
162
216
.flags = CAN_FRAME_IDE ,
163
217
};
164
218
double input = 0 ;
165
219
166
- if (vesc_can -> type == VESC_CAN_TYPE_VELOCITY && armed ) {
167
- input = ctx -> actuators .velocity [vesc_can -> index ];
220
+ if (act -> type == VESC_CAN_TYPE_VELOCITY && armed ) {
221
+ input = ctx -> actuators .velocity [act -> index ];
168
222
}
169
223
170
- int32_t erpm = vesc_can -> pole_pair * input * 60 / (2 * M_PI );
171
- frame .id = 768 + vesc_can -> vesc_id ;
224
+ int32_t erpm = act -> pole_pair * input * 60 / (2 * M_PI );
225
+ frame .id = 768 + act -> vesc_id ;
172
226
frame .data [0 ] = erpm >> 24 & 255 ;
173
227
frame .data [1 ] = erpm >> 16 & 255 ;
174
228
frame .data [2 ] = erpm >> 8 & 255 ;
@@ -179,8 +233,8 @@ static void actuate_vesc_can_update(struct context *ctx)
179
233
err = can_send (ctx -> device , & frame , K_NO_WAIT , NULL , NULL );
180
234
if (err != 0 ) {
181
235
ctx -> ready = false;
182
- LOG_ERR ("%s - send failed to VESC ID: %d (%d)\n" , vesc_can -> label ,
183
- vesc_can -> vesc_id , err );
236
+ LOG_ERR ("%s - send failed to VESC ID: %d (%d)\n" , act -> label , act -> vesc_id ,
237
+ err );
184
238
continue ;
185
239
}
186
240
perf_duration_stop (& control_latency );
@@ -224,6 +278,8 @@ static void actuate_vesc_can_run(void *p0, void *p1, void *p2)
224
278
zros_sub_update (& ctx -> sub_actuators );
225
279
}
226
280
281
+ zros_pub_update (& ctx -> pub_wheel_odometry );
282
+
227
283
// update vesc_can
228
284
actuate_vesc_can_update (ctx );
229
285
}
@@ -290,10 +346,13 @@ static int actuate_vesc_can_device_init(const struct device *dev)
290
346
.pole_pair = DT_PROP(node_id, pole_pair), \
291
347
.vesc_id = DT_PROP(node_id, vesc_id), \
292
348
.type = DT_ENUM_IDX(node_id, input_type), \
349
+ .rx_filter = {}, \
350
+ .ctx = NULL, \
351
+ .rotation = 0, \
293
352
},
294
353
295
354
#define VESC_CAN_ACTUATORS_DEFINE (inst ) \
296
- static actuator_vesc_can_t g_actuator_vesc_cans_##inst[] = { \
355
+ static struct actuator_vesc_can g_actuator_vesc_cans_##inst[] = { \
297
356
DT_FOREACH_CHILD(DT_DRV_INST(inst), VESC_CAN_ACTUATOR_DEFINE)}; \
298
357
static K_THREAD_STACK_DEFINE(g_my_stack_area_##inst, MY_STACK_SIZE); \
299
358
static struct context data_##inst = { \
@@ -311,6 +370,8 @@ static int actuate_vesc_can_device_init(const struct device *dev)
311
370
.device = DEVICE_DT_GET(DT_INST_PROP(inst, device)), \
312
371
.ready = false, \
313
372
.fd = DT_INST_PROP(inst, fd), \
373
+ .status_rate = DT_INST_PROP(inst, status_rate), \
374
+ .enable_pub_wheel_odom = DT_INST_PROP(inst, pub_wheel_odometry), \
314
375
.label = DT_NODE_FULL_NAME(DT_DRV_INST(inst)), \
315
376
}; \
316
377
VESC_CAN_ACTUATOR_SHELL(inst); \
0 commit comments