3
3
4
4
#include <stdio.h>
5
5
#include <string.h>
6
-
7
6
#include "hardware/gpio.h"
8
7
#include "hardware/pwm.h"
9
8
#include "pico/stdlib.h"
10
9
#include "pico/multicore.h"
11
-
12
10
#include "motor_driver.h"
13
-
14
11
#include "bt_hid.h"
15
12
16
- // These magic values are just taken from M0o+, not calibrated for
17
- // the Tiny chassis.
18
- #define PWM_MIN 80
19
- #define PWM_MAX (PWM_MIN + 127)
20
-
21
- static inline int8_t clamp8 (int16_t value ) {
22
- if (value > 127 ) {
23
- return 127 ;
24
- } else if (value < -128 ) {
25
- return -128 ;
26
- }
27
-
28
- return value ;
29
- }
30
-
31
- struct slice {
32
- unsigned int slice_num ;
33
- unsigned int pwm_min ;
34
- };
35
-
36
- struct half_slice {
37
- struct slice * slice ;
38
- enum pwm_chan chan ;
39
- };
40
-
41
- struct chassis {
42
- struct slice slice_l ;
43
- struct slice slice_r ;
44
-
45
- int8_t l ;
46
- int8_t r ;
47
- };
48
-
49
- struct halfslice_chassis {
50
- #define MAX_N_SLICES 4
51
- int n_slices ;
52
- struct slice slices [MAX_N_SLICES ];
53
- struct half_slice la , lb , ra , rb ;
54
-
55
- int8_t l ;
56
- int8_t r ;
57
- };
58
-
59
- static inline uint8_t abs8 (int8_t v ) {
60
- return v < 0 ? - v : v ;
61
- }
62
-
63
- void init_slice (struct slice * slice , unsigned int slice_num , unsigned int pwm_min );
64
-
65
- void __init_halfslice_pin (struct halfslice_chassis * chassis , struct half_slice * hs , uint8_t pin )
66
- {
67
- struct slice * slice = NULL ;
68
-
69
- enum pwm_chan chan = pwm_gpio_to_channel (pin );
70
- uint slice_num = pwm_gpio_to_slice_num (pin );
71
- printf ("pin %d on slice %d\n" , pin , slice_num );
72
-
73
- for (int i = 0 ; i < chassis -> n_slices ; i ++ ) {
74
- if (chassis -> slices [i ].slice_num == slice_num ) {
75
- printf ("slice %d already at idx %d\n" , slice_num , i );
76
- slice = & chassis -> slices [i ];
77
- break ;
78
- }
79
- }
80
- if (slice == NULL ) {
81
- slice = & chassis -> slices [chassis -> n_slices ];
82
- init_slice (slice , slice_num , PWM_MIN );
83
- printf ("assigned slice %d at idx %d\n" , slice_num , chassis -> n_slices );
84
- chassis -> n_slices ++ ;
85
- }
86
- gpio_set_function (pin , GPIO_FUNC_PWM );
87
-
88
- hs -> slice = slice ;
89
- hs -> chan = chan ;
90
- printf ("pin: %d, slice: %p, slice_num: %d, chan: %d\n" ,
91
- pin , slice , slice_num , chan );
92
- }
93
-
94
- void halfslice_chassis_init (struct halfslice_chassis * chassis ,
95
- uint8_t pin_la , uint8_t pin_lb , uint8_t pin_ra , uint8_t pin_rb )
96
- {
97
- __init_halfslice_pin (chassis , & chassis -> la , pin_la );
98
- __init_halfslice_pin (chassis , & chassis -> lb , pin_lb );
99
- __init_halfslice_pin (chassis , & chassis -> ra , pin_ra );
100
- __init_halfslice_pin (chassis , & chassis -> rb , pin_rb );
101
- }
102
-
103
- void halfslice_pair_set_with_brake (struct half_slice * a , struct half_slice * b , int8_t value , bool brake )
104
- {
105
- uint8_t mag = abs8 (value );
106
-
107
- if (value == 0 ) {
108
- pwm_set_chan_level (a -> slice -> slice_num , a -> chan , brake ? a -> slice -> pwm_min + 127 : 0 );
109
- pwm_set_chan_level (b -> slice -> slice_num , b -> chan , brake ? a -> slice -> pwm_min + 127 : 0 );
110
- } else if (value < 0 ) {
111
- pwm_set_chan_level (a -> slice -> slice_num , a -> chan , a -> slice -> pwm_min + mag );
112
- pwm_set_chan_level (b -> slice -> slice_num , b -> chan , 0 );
113
- } else {
114
- pwm_set_chan_level (a -> slice -> slice_num , a -> chan , 0 );
115
- pwm_set_chan_level (b -> slice -> slice_num , b -> chan , b -> slice -> pwm_min + mag );
116
- }
117
- }
118
-
119
- void halfslice_pair_set (struct half_slice * a , struct half_slice * b , int8_t value )
120
- {
121
- halfslice_pair_set_with_brake (a , b , value , false);
122
- }
123
-
124
- void halfslice_chassis_set_raw (struct halfslice_chassis * chassis , int8_t left , int8_t right )
125
- {
126
- halfslice_pair_set (& chassis -> la , & chassis -> lb , left );
127
- halfslice_pair_set (& chassis -> ra , & chassis -> rb , right );
128
-
129
- chassis -> l = left ;
130
- chassis -> r = right ;
131
- }
132
-
133
- void halfslice_chassis_set (struct halfslice_chassis * chassis , int8_t linear , int8_t rot )
13
+ static int clamp (int val , int min , int max )
134
14
{
135
- // Positive rotation == CCW == right goes faster
136
-
137
- if (linear < -127 ) {
138
- linear = -127 ;
139
- }
140
-
141
- if (rot < -127 ) {
142
- rot = -127 ;
143
- }
144
-
145
- int l = linear - rot ;
146
- int r = linear + rot ;
147
- int adj = 0 ;
148
-
149
- if (l > 127 ) {
150
- adj = l - 127 ;
151
- } else if (l < -127 ) {
152
- adj = l + 127 ;
153
- }else if (r > 127 ) {
154
- adj = r - 127 ;
155
- } else if (r < -127 ) {
156
- adj = r + 127 ;
15
+ if ( val > max )
16
+ {
17
+ return max ;
157
18
}
158
-
159
- l -= adj ;
160
- r -= adj ;
161
-
162
- // FIXME: Motor directions should be a parameter
163
- r = - r ;
164
-
165
- halfslice_chassis_set_raw (chassis , l , r );
166
- }
167
-
168
- void init_slice (struct slice * slice , unsigned int slice_num , unsigned int pwm_min )
169
- {
170
- slice -> slice_num = slice_num ;
171
- slice -> pwm_min = pwm_min ;
172
- pwm_set_wrap (slice -> slice_num , slice -> pwm_min + 127 + 1 );
173
- pwm_set_chan_level (slice -> slice_num , PWM_CHAN_A , 0 );
174
- pwm_set_chan_level (slice -> slice_num , PWM_CHAN_B , 0 );
175
- pwm_set_enabled (slice -> slice_num , true);
176
- }
177
-
178
- void chassis_init (struct chassis * chassis , uint8_t pin_la , uint8_t pin_ra )
179
- {
180
-
181
- init_slice (& chassis -> slice_l , pwm_gpio_to_slice_num (pin_la ), PWM_MIN );
182
- gpio_set_function (pin_la , GPIO_FUNC_PWM );
183
- gpio_set_function (pin_la + 1 , GPIO_FUNC_PWM );
184
- init_slice (& chassis -> slice_r , pwm_gpio_to_slice_num (pin_ra ), PWM_MIN );
185
- gpio_set_function (pin_ra , GPIO_FUNC_PWM );
186
- gpio_set_function (pin_ra + 1 , GPIO_FUNC_PWM );
187
- }
188
-
189
- void slice_set_with_brake (struct slice * slice , int8_t value , bool brake )
190
- {
191
- uint8_t mag = abs8 (value );
192
-
193
- if (value == 0 ) {
194
- pwm_set_both_levels (slice -> slice_num , brake ? slice -> pwm_min + 127 : 0 , brake ? slice -> pwm_min + 127 : 0 );
195
- } else if (value < 0 ) {
196
- pwm_set_both_levels (slice -> slice_num , slice -> pwm_min + mag , 0 );
197
- } else {
198
- pwm_set_both_levels (slice -> slice_num , 0 , slice -> pwm_min + mag );
19
+ if ( val < min )
20
+ {
21
+ return min ;
199
22
}
23
+ return val ;
200
24
}
201
25
202
- void slice_set (struct slice * slice , int8_t value )
203
- {
204
- slice_set_with_brake (slice , value , false);
205
- }
206
-
207
- void chassis_set_raw (struct chassis * chassis , int8_t left , int8_t right )
208
- {
209
- slice_set (& chassis -> slice_l , left );
210
- slice_set (& chassis -> slice_r , right );
211
-
212
- chassis -> l = left ;
213
- chassis -> r = right ;
214
- }
215
-
216
- void chassis_set (struct chassis * chassis , int8_t linear , int8_t rot )
26
+ static void update_motor_driver_from_control_input ( struct bt_hid_state * state )
217
27
{
218
- // Positive rotation == CCW == right goes faster
219
28
220
- if (linear < -127 ) {
221
- linear = -127 ;
29
+ // printf("buttons: %04x, l: %d,%d, r: %d,%d, l2,r2: %d,%d hat: %d\n",
30
+ // state->buttons, state->lx, state->ly, state->rx, state->ry,
31
+ // state->l2, state->r2, state->hat);
32
+
33
+ // Motor Mixer
34
+ int forward_speed = (256 - state -> ly ) - 128 ; // 128 is full forward, 0 is stop, -128 is backwards
35
+ int swerve_right_rate = (state -> rx - 128 ); // 128 is max right swerve rate, 0 is no swerve, -128 is max left swerve
36
+
37
+ int left_output = forward_speed ;
38
+ int right_output = forward_speed ;
39
+ if ( forward_speed > 0 )
40
+ {
41
+ if ( swerve_right_rate > 0 )
42
+ {
43
+ right_output -= swerve_right_rate / 2 ;
44
+ right_output = clamp (right_output , 0 , 128 );
45
+ }
46
+ else if ( swerve_right_rate < 0 )
47
+ {
48
+ left_output -= swerve_right_rate / 2 ;
49
+ left_output = clamp (left_output , 0 , 128 );
50
+ }
222
51
}
223
-
224
- if (rot < -127 ) {
225
- rot = -127 ;
52
+ else if ( forward_speed < 0 )
53
+ {
54
+ if ( swerve_right_rate > 0 )
55
+ {
56
+ right_output += swerve_right_rate / 2 ;
57
+ right_output = clamp (right_output , -127 , 0 );
58
+ }
59
+ else if ( swerve_right_rate < 0 )
60
+ {
61
+ left_output += swerve_right_rate / 2 ;
62
+ left_output = clamp (left_output , -127 , 0 );
63
+ }
226
64
}
227
-
228
- int l = linear - rot ;
229
- int r = linear + rot ;
230
- int adj = 0 ;
231
-
232
- if (l > 127 ) {
233
- adj = l - 127 ;
234
- } else if (l < -127 ) {
235
- adj = l + 127 ;
236
- }else if (r > 127 ) {
237
- adj = r - 127 ;
238
- } else if (r < -127 ) {
239
- adj = r + 127 ;
65
+ else
66
+ {
67
+ if ( swerve_right_rate != 0 )
68
+ {
69
+ // rotate in place
70
+ // This handles both rotate left and right as left will be negative and right positive
71
+ left_output = swerve_right_rate / 2 ;
72
+ right_output = -1 * swerve_right_rate / 2 ;
73
+ }
74
+ // otherwise no rotation
240
75
}
241
76
242
- l -= adj ;
243
- r -= adj ;
244
-
245
- // FIXME: Motor directions should be a parameter
246
- r = - r ;
247
-
248
- chassis_set_raw (chassis , l , r );
249
- }
250
-
251
- static void update_motor_driver_from_control_input ( struct halfslice_chassis * chassis , struct bt_hid_state * state )
252
- {
253
-
254
- printf ("buttons: %04x, l: %d,%d, r: %d,%d, l2,r2: %d,%d hat: %d\n" ,
255
- state -> buttons , state -> lx , state -> ly , state -> rx , state -> ry ,
256
- state -> l2 , state -> r2 , state -> hat );
77
+ left_output = clamp (left_output , -127 , 128 );
78
+ right_output = clamp (right_output , -127 , 128 );
257
79
258
- // int8_t linear_scaling =
259
-
260
- // motor_driver_set_speed( float val );
261
- // motor_driver_set_direction( bool forward );
262
-
263
- float speed_scale = 1.0 ;
264
- int8_t linear = clamp8 (- (state -> ly - 128 ) * speed_scale );
265
- int8_t rot = clamp8 (- (state -> rx - 128 ));
266
- halfslice_chassis_set ( chassis , linear , rot );
80
+ // Set motor driver
81
+ motor_driver_set_left ( left_output );
82
+ motor_driver_set_right ( right_output );
267
83
}
268
84
269
85
enum SystemStates
@@ -273,23 +89,21 @@ enum SystemStates
273
89
// Add additional state here...
274
90
};
275
91
276
- void main (void ) {
277
- stdio_init_all ();
278
-
279
- multicore_launch_core1 (bt_main );
280
- // Wait for init (should do a handshake with the fifo here?)
281
- sleep_ms (1000 );
282
-
283
- //struct chassis chassis = { 0 };
284
- //chassis_init(&chassis, 6, 8);
285
- struct halfslice_chassis chassis = { 0 };
286
- halfslice_chassis_init (& chassis , 19 , 17 , 16 , 15 );
287
-
92
+ void main (void )
93
+ {
94
+ // Variables used to control the main state machine
288
95
enum SystemStates next_system_state = SystemState_DISCONNECTED ;
289
96
enum SystemStates system_state = SystemState_DISCONNECTED ;
290
97
enum SystemStates prev_system_state = SystemState_DISCONNECTED ;
291
-
98
+ // Structure used to hold the Bluetooth controller data
292
99
struct bt_hid_state controller_state = {0 };
100
+
101
+ stdio_init_all ();
102
+ multicore_launch_core1 (bt_main );
103
+ // Wait for init
104
+ sleep_ms (1000 );
105
+ motor_driver_setup ();
106
+
293
107
while ( 1 )
294
108
{
295
109
const bool system_state_entered = ( system_state != prev_system_state );
@@ -302,7 +116,7 @@ void main(void) {
302
116
{
303
117
// When entering the state run these functions 1 time.
304
118
// Set the motors to a safe state.
305
- motor_driver_disable ();
119
+ motor_driver_stop ();
306
120
}
307
121
// Run the following continuously while in the disconnected mode.
308
122
// Check to see if we are connected.
@@ -317,15 +131,14 @@ void main(void) {
317
131
if ( system_state_entered )
318
132
{
319
133
// When entering the state run these functions 1 time.
320
- // Set the motors to a safe state.
321
- motor_driver_enable ();
134
+ printf ("SystemState_CONNECTED\n" );
322
135
}
323
136
// Check to see if we are connected.
324
137
// Handle the latest controller input.
325
138
if ( bt_hid_is_connected () )
326
139
{
327
140
// handle commands and update the motor.
328
- update_motor_driver_from_control_input (& chassis , & controller_state );
141
+ update_motor_driver_from_control_input (& controller_state );
329
142
}
330
143
else
331
144
{
0 commit comments