Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

One pedal drive #262

Closed
wants to merge 16 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions projects/motor_controller/inc/motor_can.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@
#define TORQUE_CONTROL_VEL 20000 // unobtainable rpm for current control
#define VEL_TO_RPM_RATIO 1.0 // TODO: set actual ratio, m/s to motor rpm

#define MAX_COASTING_THRESHOLD 0.4 // Max pedal threshold when coasting at speeds > 8 km/h
#define MAX_OPD_SPEED 8 // Max car speed before one pedal driving threshold maxes out
#define CONVERT_VELOCITY_TO_KPH 3.6 // Converts m/s to km/h
#define COASTING_THRESHOLD_SCALE 0.05 // Scaling value to determine coasting threshold

#define DRIVER_CONTROL_BASE 0x1
#define MOTOR_CONTROLLER_BASE_L 0x40
#define MOTOR_CONTROLLER_BASE_R 0x80
Expand Down
64 changes: 53 additions & 11 deletions projects/motor_controller/src/motor_can.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,13 @@ typedef enum DriveState {
// extra drive state types used only by mci
CRUISE,
BRAKE,
OPD_BRAKE,
} DriveState;

static float s_target_current;
static float s_target_velocity;
static float s_car_velocity_l = 0.0;
static float s_car_velocity_r = 0.0;

static float prv_get_float(uint32_t u) {
union {
Expand All @@ -48,20 +51,53 @@ static float prv_get_float(uint32_t u) {
return fu.f;
}

static float prv_one_pedal_drive_current(float throttle_percent, float car_velocity,
DriveState *drive_state) {
float threshold = 0.0;
if (car_velocity <= MAX_OPD_SPEED) {
threshold = car_velocity * COASTING_THRESHOLD_SCALE;
} else {
threshold = MAX_COASTING_THRESHOLD;
}

if (throttle_percent <= threshold + 0.05 && throttle_percent >= threshold - 0.05) {
return 0.0;
}

if (throttle_percent >= threshold) {
return (throttle_percent - threshold) / (1 - threshold);
} else {
*drive_state = BRAKE;
return (threshold - throttle_percent) / (threshold);
}
LOG_DEBUG("ERROR: One pedal throttle not calculated\n");
return 0.0;
}

static void prv_update_target_current_velocity() {
float throttle_percent = prv_get_float(get_pedal_output_throttle_output());
float brake_percent = prv_get_float(get_pedal_output_brake_output());
float target_vel = prv_get_float(get_drive_output_target_velocity()) * VEL_TO_RPM_RATIO;
float car_vel = (s_car_velocity_l + s_car_velocity_r) / 2;

DriveState drive_state = get_drive_output_drive_state();
bool regen = get_drive_output_regen_braking();

// Regen returns a value btwn 0-100 to represent the max regen we can preform
// 0 means our cells max voltage is close to 4.2V or regen is off so we should stop regen braking
// 100 means we are below 4.0V so regen braking is allowed
float regen = prv_get_float(get_drive_output_regen_braking());
bool cruise = get_drive_output_cruise_control();

if (cruise && throttle_percent > CRUISE_THROTTLE_THRESHOLD) {
drive_state = DRIVE;
// TODO: Update cruise_throttle_threshold so the driver must demand more current than is already
// being supplied
if (drive_state == DRIVE && cruise && throttle_percent <= CRUISE_THROTTLE_THRESHOLD) {
drive_state = CRUISE;
}
if (brake_percent > 0 || (throttle_percent == 0 && drive_state != CRUISE)) {
drive_state = BRAKE;
}
if (brake_percent > 0 || throttle_percent == 0) {
drive_state = regen ? BRAKE : NEUTRAL;
if (drive_state == DRIVE || drive_state == REVERSE) {
throttle_percent = prv_one_pedal_drive_current(throttle_percent, car_vel, &drive_state);
}

// set target current and velocity based on drive state
Expand All @@ -71,6 +107,10 @@ static void prv_update_target_current_velocity() {
s_target_current = throttle_percent;
s_target_velocity = TORQUE_CONTROL_VEL;
break;
case NEUTRAL:
s_target_current = 0;
s_target_velocity = 0;
break;
case REVERSE:
s_target_current = throttle_percent;
s_target_velocity = -TORQUE_CONTROL_VEL;
Expand All @@ -79,12 +119,12 @@ static void prv_update_target_current_velocity() {
s_target_current = ACCERLATION_FORCE;
s_target_velocity = target_vel;
break;
case BRAKE:
s_target_current = ACCERLATION_FORCE;
s_target_velocity = 0;
break;
case NEUTRAL:
s_target_current = 0;
case BRAKE: // When braking and regen is off it should be the same as NEUTRAL. regen = 0
if (throttle_percent > regen) {
s_target_current = regen;
} else {
s_target_current = throttle_percent;
}
s_target_velocity = 0;
break;
default:
Expand Down Expand Up @@ -130,9 +170,11 @@ static void motor_controller_rx_all() {

case MOTOR_CONTROLLER_BASE_L + VEL_MEASUREMENT:
set_motor_velocity_velocity_l(prv_get_float(msg.data_u32[0]) * VELOCITY_SCALE);
s_car_velocity_l = prv_get_float(msg.data_u32[1]) * CONVERT_VELOCITY_TO_KPH;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know this file used this msg struct already but could you link to the doc where the uint32's value is defined? The link up top is dead

break;
case MOTOR_CONTROLLER_BASE_R + VEL_MEASUREMENT:
set_motor_velocity_velocity_r(prv_get_float(msg.data_u32[0]) * VELOCITY_SCALE);
s_car_velocity_r = prv_get_float(msg.data_u32[1]) * CONVERT_VELOCITY_TO_KPH;
break;

case MOTOR_CONTROLLER_BASE_L + HEAT_SINK_MOTOR_TEMP:
Expand Down
Loading