Skip to content

Commit d1b962b

Browse files
authored
Merge pull request vedderb#392 from luna-cycle/luna_bbshd_support
Luna bbshd support
2 parents 95c6717 + b7caa46 commit d1b962b

12 files changed

+2010
-137
lines changed

applications/app.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ void app_set_configuration(app_configuration *conf) {
125125
break;
126126

127127
case APP_ADC_PAS:
128-
app_adc_start(true);
128+
app_adc_start(false);
129129
app_pas_start(false);
130130
break;
131131

applications/app.h

+1
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ void app_pas_stop(void);
8181
bool app_pas_is_running(void);
8282
void app_pas_configure(pas_config *conf);
8383
float app_pas_get_current_target_rel(void);
84+
void app_pas_set_current_sub_scaling(float current_sub_scaling);
8485

8586
// Custom apps
8687
void app_custom_start(void);

applications/app_pas.c

+58-16
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232

3333
// Settings
3434
#define PEDAL_INPUT_TIMEOUT 0.2
35+
#define MAX_MS_WITHOUT_CADENCE 5000
3536
#define MIN_MS_WITHOUT_POWER 500
3637
#define FILTER_SAMPLES 5
3738
#define RPM_FILTER_SAMPLES 8
@@ -42,6 +43,7 @@ static THD_WORKING_AREA(pas_thread_wa, 1024);
4243

4344
// Private variables
4445
static volatile pas_config config;
46+
static volatile float sub_scaling = 1.0;
4547
static volatile float output_current_rel = 0.0;
4648
static volatile float ms_without_power = 0.0;
4749
static volatile float max_pulse_period = 0.0;
@@ -51,7 +53,14 @@ static volatile float pedal_rpm = 0;
5153
static volatile bool primary_output = false;
5254
static volatile bool stop_now = true;
5355
static volatile bool is_running = false;
56+
static volatile float torque_ratio = 0.0;
5457

58+
/**
59+
* Configure and initialize PAS application
60+
*
61+
* @param conf
62+
* App config
63+
*/
5564
void app_pas_configure(pas_config *conf) {
5665
config = *conf;
5766
ms_without_power = 0.0;
@@ -63,10 +72,7 @@ void app_pas_configure(pas_config *conf) {
6372
// if pedal spins at x3 the end rpm, assume its beyond limits
6473
min_pedal_period = 1.0 / ((config.pedal_rpm_end * 3.0 / 60.0));
6574

66-
if (config.invert_pedal_direction == true )
67-
direction_conf= -1.0;
68-
else
69-
direction_conf = 1.0;
75+
(config.invert_pedal_direction) ? (direction_conf = -1.0) : (direction_conf = 1.0);
7076
}
7177

7278
/**
@@ -101,19 +107,24 @@ void app_pas_stop(void) {
101107
}
102108
}
103109

110+
void app_pas_set_current_sub_scaling(float current_sub_scaling) {
111+
sub_scaling = current_sub_scaling;
112+
}
113+
104114
float app_pas_get_current_target_rel(void) {
105115
return output_current_rel;
106116
}
107117

108118
void pas_event_handler(void) {
109119
#ifdef HW_PAS1_PORT
110120
const int8_t QEM[] = {0,-1,1,2,1,0,2,-1,-1,2,0,1,2,1,-1,0}; // Quadrature Encoder Matrix
111-
float direction_qem;
121+
int8_t direction_qem;
112122
uint8_t new_state;
113123
static uint8_t old_state = 0;
114124
static float old_timestamp = 0;
115125
static float inactivity_time = 0;
116126
static float period_filtered = 0;
127+
static int32_t correct_direction_counter = 0;
117128

118129
uint8_t PAS1_level = palReadPad(HW_PAS1_PORT, HW_PAS1_PIN);
119130
uint8_t PAS2_level = palReadPad(HW_PAS2_PORT, HW_PAS2_PIN);
@@ -122,10 +133,19 @@ void pas_event_handler(void) {
122133
direction_qem = (float) QEM[old_state * 4 + new_state];
123134
old_state = new_state;
124135

136+
// Require several quadrature events in the right direction to prevent vibrations from
137+
// engging PAS
138+
int8_t direction = (direction_conf * direction_qem);
139+
140+
switch(direction) {
141+
case 1: correct_direction_counter++; break;
142+
case -1:correct_direction_counter = 0; break;
143+
}
144+
125145
const float timestamp = (float)chVTGetSystemTimeX() / (float)CH_CFG_ST_FREQUENCY;
126146

127147
// sensors are poorly placed, so use only one rising edge as reference
128-
if(new_state == 3) {
148+
if( (new_state == 3) && (correct_direction_counter >= 4) ) {
129149
float period = (timestamp - old_timestamp) * (float)config.magnets;
130150
old_timestamp = timestamp;
131151

@@ -135,7 +155,7 @@ void pas_event_handler(void) {
135155
return;
136156
}
137157
pedal_rpm = 60.0 / period_filtered;
138-
pedal_rpm *= (direction_conf * direction_qem);
158+
pedal_rpm *= (direction_conf * (float)direction_qem);
139159
inactivity_time = 0.0;
140160
}
141161
else {
@@ -177,7 +197,7 @@ static THD_FUNCTION(pas_thread, arg) {
177197
return;
178198
}
179199

180-
pas_event_handler(); // this should happen inside an ISR instead of being polled
200+
pas_event_handler(); // this could happen inside an ISR instead of being polled
181201

182202
// For safe start when fault codes occur
183203
if (mc_interface_get_fault() != FAULT_CODE_NONE) {
@@ -188,28 +208,50 @@ static THD_FUNCTION(pas_thread, arg) {
188208
continue;
189209
}
190210

191-
// Map the rpm to assist level
192211
switch (config.ctrl_type) {
193212
case PAS_CTRL_TYPE_NONE:
194213
output = 0.0;
195214
break;
196215
case PAS_CTRL_TYPE_CADENCE:
216+
// Map pedal rpm to assist level
217+
197218
// NOTE: If the limits are the same a numerical instability is approached, so in that case
198219
// just use on/off control (which is what setting the limits to the same value essentially means).
199220
if (config.pedal_rpm_end > (config.pedal_rpm_start + 1.0)) {
200-
output = utils_map(pedal_rpm, config.pedal_rpm_start, config.pedal_rpm_end, 0.0, config.current_scaling);
201-
utils_truncate_number(&output, 0.0, config.current_scaling);
221+
output = utils_map(pedal_rpm, config.pedal_rpm_start, config.pedal_rpm_end, 0.0, config.current_scaling * sub_scaling);
222+
utils_truncate_number(&output, 0.0, config.current_scaling * sub_scaling);
202223
} else {
203224
if (pedal_rpm > config.pedal_rpm_end) {
204-
output = config.current_scaling;
225+
output = config.current_scaling * sub_scaling;
205226
} else {
206227
output = 0.0;
207228
}
208229
}
209230
break;
210-
case PAS_CTRL_TYPE_CONSTANT_TORQUE:
211-
output = pedal_rpm > config.pedal_rpm_start ? config.current_scaling : 0;
212-
break;
231+
232+
#ifdef HW_HAS_PAS_TORQUE_SENSOR
233+
case PAS_CTRL_TYPE_TORQUE:
234+
{
235+
torque_ratio = hw_get_PAS_torque();
236+
output = torque_ratio * config.current_scaling * sub_scaling;
237+
utils_truncate_number(&output, 0.0, config.current_scaling * sub_scaling);
238+
}
239+
/* fall through */
240+
case PAS_CTRL_TYPE_TORQUE_WITH_CADENCE_TIMEOUT:
241+
{
242+
// disable assistance if torque has been sensed for >5sec without any pedal movement. Prevents
243+
// motor overtemps when the rider is just resting on the pedals
244+
static float ms_without_cadence_or_torque = 0.0;
245+
if(output == 0.0 || pedal_rpm > 0) {
246+
ms_without_cadence_or_torque = 0.0;
247+
} else {
248+
ms_without_cadence_or_torque += (1000.0 * (float)sleep_time) / (float)CH_CFG_ST_FREQUENCY;
249+
if(ms_without_cadence_or_torque > MAX_MS_WITHOUT_CADENCE) {
250+
output = 0.0;
251+
}
252+
}
253+
}
254+
#endif
213255
default:
214256
break;
215257
}
@@ -222,7 +264,7 @@ static THD_FUNCTION(pas_thread, arg) {
222264
if (ramp_time > 0.01) {
223265
const float ramp_step = (float)ST2MS(chVTTimeElapsedSinceX(last_time)) / (ramp_time * 1000.0);
224266
utils_step_towards(&output_ramp, output, ramp_step);
225-
utils_truncate_number(&output_ramp, 0.0, config.current_scaling);
267+
utils_truncate_number(&output_ramp, 0.0, config.current_scaling * sub_scaling);
226268

227269
last_time = chVTGetSystemTimeX();
228270
output = output_ramp;

datatypes.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -583,7 +583,8 @@ typedef enum {
583583
typedef enum {
584584
PAS_CTRL_TYPE_NONE = 0,
585585
PAS_CTRL_TYPE_CADENCE,
586-
PAS_CTRL_TYPE_CONSTANT_TORQUE
586+
PAS_CTRL_TYPE_TORQUE,
587+
PAS_CTRL_TYPE_TORQUE_WITH_CADENCE_TIMEOUT
587588
} pas_control_type;
588589

589590
// PAS sensor types

0 commit comments

Comments
 (0)