Skip to content

Commit a1f9521

Browse files
committed
- added motor driver for basic control no pwm
1 parent 9bb9052 commit a1f9521

File tree

4 files changed

+157
-282
lines changed

4 files changed

+157
-282
lines changed

main_app.c

Lines changed: 72 additions & 259 deletions
Original file line numberDiff line numberDiff line change
@@ -3,267 +3,83 @@
33

44
#include <stdio.h>
55
#include <string.h>
6-
76
#include "hardware/gpio.h"
87
#include "hardware/pwm.h"
98
#include "pico/stdlib.h"
109
#include "pico/multicore.h"
11-
1210
#include "motor_driver.h"
13-
1411
#include "bt_hid.h"
1512

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)
13414
{
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;
15718
}
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;
19922
}
23+
return val;
20024
}
20125

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 )
21727
{
218-
// Positive rotation == CCW == right goes faster
21928

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+
}
22251
}
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+
}
22664
}
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
24075
}
24176

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);
25779

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 );
26783
}
26884

26985
enum SystemStates
@@ -273,23 +89,21 @@ enum SystemStates
27389
// Add additional state here...
27490
};
27591

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
28895
enum SystemStates next_system_state = SystemState_DISCONNECTED;
28996
enum SystemStates system_state = SystemState_DISCONNECTED;
29097
enum SystemStates prev_system_state = SystemState_DISCONNECTED;
291-
98+
// Structure used to hold the Bluetooth controller data
29299
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+
293107
while ( 1 )
294108
{
295109
const bool system_state_entered = ( system_state != prev_system_state );
@@ -302,7 +116,7 @@ void main(void) {
302116
{
303117
// When entering the state run these functions 1 time.
304118
// Set the motors to a safe state.
305-
motor_driver_disable();
119+
motor_driver_stop();
306120
}
307121
// Run the following continuously while in the disconnected mode.
308122
// Check to see if we are connected.
@@ -317,15 +131,14 @@ void main(void) {
317131
if( system_state_entered )
318132
{
319133
// 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");
322135
}
323136
// Check to see if we are connected.
324137
// Handle the latest controller input.
325138
if( bt_hid_is_connected() )
326139
{
327140
// 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);
329142
}
330143
else
331144
{

0 commit comments

Comments
 (0)