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

Adi/gps error handling #1399

Merged
merged 47 commits into from
Jan 18, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
b0dcc05
Uncommented GPS-related code
1mackenziekyle Sep 17, 2024
1794f04
Broadcast EKF data
philam2001 Oct 18, 2024
6cd2a11
Log messages
philam2001 Oct 22, 2024
e884293
revert submodules
philam2001 Oct 26, 2024
75e3a41
Update comment
philam2001 Oct 27, 2024
5376834
pls fix my issue
philam2001 Nov 4, 2024
578f973
Comment out unused
philam2001 Nov 5, 2024
e346349
Clean up EKF Nav code
philam2001 Nov 11, 2024
909928f
Specify euler naming
philam2001 Nov 11, 2024
897e5f0
gps error handling in progress
Aditya-Dhiman4 Nov 23, 2024
e98c47a
added can message for error handling
Aditya-Dhiman4 Nov 24, 2024
2e24504
removed some comments
Aditya-Dhiman4 Nov 24, 2024
308de6b
added simple velocity calculations, can msg handling may need to be c…
Aditya-Dhiman4 Nov 24, 2024
9d013e3
added check in io to prevent can msg spam
Aditya-Dhiman4 Nov 25, 2024
6c70715
merged master into gps-error-handling branch
Aditya-Dhiman4 Nov 29, 2024
80e18c4
changes
Aditya-Dhiman4 Nov 29, 2024
4024680
Broadcast EKF data
philam2001 Oct 18, 2024
bb9f133
Log messages
philam2001 Oct 22, 2024
564b646
Comment out unused
philam2001 Nov 5, 2024
d8d7886
gps error handling in progress
Aditya-Dhiman4 Nov 23, 2024
200faea
added can message for error handling
Aditya-Dhiman4 Nov 24, 2024
05ed573
removed some comments
Aditya-Dhiman4 Nov 24, 2024
ee09d1a
added simple velocity calculations, can msg handling may need to be c…
Aditya-Dhiman4 Nov 24, 2024
eb858ac
added check in io to prevent can msg spam
Aditya-Dhiman4 Nov 25, 2024
ee284e9
added functions to obtain angular velocity from imu
Aditya-Dhiman4 Nov 30, 2024
b013efa
Merge branch 'adi/gps-error-handling' of https://github.com/UBCFormul…
Aditya-Dhiman4 Nov 30, 2024
33dc9d6
added imu gyro functions, added simple velocity calculations
Aditya-Dhiman4 Nov 30, 2024
60d3720
imu code works, outputs angular velocities
Aditya-Dhiman4 Nov 30, 2024
0a00bd2
added review changes
Aditya-Dhiman4 Nov 30, 2024
ccb8875
updated velocity calculation
Aditya-Dhiman4 Nov 30, 2024
a72712a
commented out unused function
Aditya-Dhiman4 Nov 30, 2024
6444f32
Merge branch 'master' of https://github.com/UBCFormulaElectric/Consol…
Aditya-Dhiman4 Dec 3, 2024
00556fb
cleaned up code
Aditya-Dhiman4 Dec 7, 2024
7edb9c3
Merge branch 'master' into adi/gps-error-handling
Lucien950 Dec 28, 2024
f69c233
added review changes
Aditya-Dhiman4 Dec 30, 2024
16d23de
added back is_moving logic, created seperate CAN msg for calc velocit…
Aditya-Dhiman4 Jan 6, 2025
d1d95e4
Clean + fix bug
philam2001 Jan 12, 2025
20c335c
Fix regen test affected
philam2001 Jan 12, 2025
a7ed3a7
Finishing Touches
Aditya-Dhiman4 Jan 12, 2025
7347070
merge master into adi/gps-error-handling
Aditya-Dhiman4 Jan 12, 2025
07b23e0
added velocity test for 0 rpms
Aditya-Dhiman4 Jan 12, 2025
f6d9300
fixed formatting
Aditya-Dhiman4 Jan 13, 2025
1e49777
Merge branch 'master' of github.com:UBCFormulaElectric/Consolidated-F…
Aditya-Dhiman4 Jan 13, 2025
269310c
removed is_moving, added ekf status through CAN and tests
Aditya-Dhiman4 Jan 15, 2025
7ae9bf8
clang format
Aditya-Dhiman4 Jan 15, 2025
73b6c18
Cleaned up code, set status field in VelocityData
Aditya-Dhiman4 Jan 18, 2025
553a308
Merge branch 'master' of github.com:UBCFormulaElectric/Consolidated-F…
Aditya-Dhiman4 Jan 18, 2025
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
28 changes: 26 additions & 2 deletions can_bus/quadruna/VC/VC_tx.json
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,12 @@
"min": -150,
"max": 150,
"unit": "km/h"
},
"VehicleVelocityCalculated": {
"resolution": 0.01,
"min": -150,
"max": 150,
"unit": "km/h"
}
}
},
Expand Down Expand Up @@ -691,10 +697,10 @@
}
}
},
"ImuLinearAcceleration": {
"ImuData": {
"msg_id": 225,
"cycle_time": 100,
"description": "Linear acceleration in x, y and z direction from the IMU",
"description": "Linear Acceleration and Angular Velocity in x, y and z direction from the IMU",
"signals": {
"ImuAccelerationX": {
"resolution": 0.1,
Expand All @@ -713,6 +719,24 @@
"min": 0,
"max": 20,
"unit": "m/s"
},
"ImuAngularVelocityRoll": {
"resolution": 0.1,
"min": -360,
"max": 360,
"unit": "deg/s"
},
"ImuAngularVelocityPitch": {
"resolution": 0.1,
"min": -360,
"max": 360,
"unit": "deg/s"
},
"ImuAngularVelocityYaw": {
"resolution": 0.1,
"min": -360,
philam2001 marked this conversation as resolved.
Show resolved Hide resolved
"max": 360,
"unit": "deg/s"
}
}
},
Expand Down
55 changes: 48 additions & 7 deletions firmware/quadruna/VC/src/app/app_sbgEllipse.c
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
#include <assert.h>
#include "app_sbgEllipse.h"
#include "app_canTx.h"
#include "app_canRx.h"
#include "app_utils.h"
#include "app_units.h"
#include "io_sbgEllipse.h"
#include "app_vehicleDynamicsConstants.h"
#include "io_log.h"

void app_sbgEllipse_broadcast()
{
Expand All @@ -21,10 +23,15 @@ void app_sbgEllipse_broadcast()
// const uint32_t timestamp_us = io_sbgEllipse_getTimestampUs();
// app_canTx_VC_EllipseTimestamp_set(timestamp_us);

// Velocity EKF
const float ekf_vel_N = io_sbgEllipse_getEkfNavVelocityData()->north;
const float ekf_vel_E = io_sbgEllipse_getEkfNavVelocityData()->east;
const float ekf_vel_D = io_sbgEllipse_getEkfNavVelocityData()->down;
VelocityData velocity_calculated;

// calculating velocity data based on wheel speed
app_sbgEllipse_calculateVelocity(&velocity_calculated);

// EKF
float ekf_vel_N = io_sbgEllipse_getEkfNavVelocityData()->north;
float ekf_vel_E = io_sbgEllipse_getEkfNavVelocityData()->east;
float ekf_vel_D = io_sbgEllipse_getEkfNavVelocityData()->down;

const float ekf_vel_N_accuracy = io_sbgEllipse_getEkfNavVelocityData()->north_std_dev;
const float ekf_vel_E_accuracy = io_sbgEllipse_getEkfNavVelocityData()->east_std_dev;
Expand All @@ -38,9 +45,21 @@ void app_sbgEllipse_broadcast()
app_canTx_VC_VelocityEastAccuracy_set(ekf_vel_E_accuracy);
app_canTx_VC_VelocityDownAccuracy_set(ekf_vel_D_accuracy);

const float vehicle_velocity = sqrtf(SQUARE(ekf_vel_N) + SQUARE(ekf_vel_E) + SQUARE(ekf_vel_D));
const float vehicle_velocity = sqrtf(SQUARE(ekf_vel_N) + SQUARE(ekf_vel_E) + SQUARE(ekf_vel_D));
const float vehicle_velocity_calculated = MPS_TO_KMH(velocity_calculated.north);

uint32_t ekf_sol_mode = io_sbgEllipse_getEkfSolutionMode();

if (ekf_sol_mode < NUM_VC_EKF_STATUS_CHOICES)
{
app_canTx_VC_EkfSolutionMode_set((VcEkfStatus)ekf_sol_mode);
}

app_canTx_VC_VehicleVelocity_set(MPS_TO_KMH(vehicle_velocity));
// determines when to use calculated or gps velocity, will be externed later
// bool use_calculated_velocity = ekf_sol_mode == POSITION;

app_canTx_VC_VehicleVelocity_set(vehicle_velocity);
app_canTx_VC_VehicleVelocityCalculated_set(vehicle_velocity_calculated);

// Position EKF
// const double ekf_pos_lat = io_sbgEllipse_getEkfNavPositionData()->latitude;
Expand Down Expand Up @@ -76,3 +95,25 @@ void app_sbgEllipse_broadcast()
app_canTx_VC_EulerAnglesPitch_set(euler_pitch);
app_canTx_VC_EulerAnglesYaw_set(euler_yaw);
}

void app_sbgEllipse_calculateVelocity(VelocityData *velocity)
{
// These velocity calculations are not going to be super accurate because it
// currently does not compute a proper relative y-axis velocity because no yaw rate

const float rightMotorRPM = (float)-app_canRx_INVR_MotorSpeed_get();
const float leftMotorRPM = (float)app_canRx_INVL_MotorSpeed_get();

float leftWheelVelocity = MOTOR_RPM_TO_KMH(leftMotorRPM);
float rightWheelVelocity = MOTOR_RPM_TO_KMH(rightMotorRPM);

float velocityX = (leftWheelVelocity + rightWheelVelocity) / 2.0f;
philam2001 marked this conversation as resolved.
Show resolved Hide resolved

// This is technically velocity in the x-axis as it is relative
velocity->north = velocityX;

// This is technically velocity in the y-axis as it is relative
velocity->east = 0;

velocity->down = 0;
}
7 changes: 7 additions & 0 deletions firmware/quadruna/VC/src/app/app_sbgEllipse.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
#pragma once

#include <stdint.h>
#include "io_sbgEllipse.h"

/*
* Broadcast sensor outputs over CAN.
*/
void app_sbgEllipse_broadcast(void);

/*
* Calculate vehicle velocity based on motor RPM
*/
void app_sbgEllipse_calculateVelocity(VelocityData *velocity);
15 changes: 15 additions & 0 deletions firmware/quadruna/VC/src/app/states/app_allStates.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,21 @@ void app_allStates_runOnTick100Hz(void)
app_canTx_VC_ImuAccelerationZ_set(lin_accel_z);
}

float angular_velocity_roll = 0.0f;
float angular_velocity_pitch = 0.0f;
float angular_velocity_yaw = 0.0f;

bool has_ang_vel_roll = io_imu_getAngularVelocityRoll(&angular_velocity_roll);
bool has_ang_vel_pitch = io_imu_getAngularVelocityPitch(&angular_velocity_pitch);
bool has_ang_vel_yaw = io_imu_getAngularVelocityYaw(&angular_velocity_yaw);

if (has_ang_vel_roll && has_ang_vel_pitch && has_ang_vel_yaw)
{
app_canTx_VC_ImuAngularVelocityRoll_set(angular_velocity_roll);
app_canTx_VC_ImuAngularVelocityPitch_set(angular_velocity_pitch);
app_canTx_VC_ImuAngularVelocityYaw_set(angular_velocity_yaw);
}

app_heartbeatMonitor_checkIn(&hb_monitor);

if (heartbeat_cycles <= IGNORE_HEARTBEAT_CYCLES) // TODO make this part of the heartbeat monitor
Expand Down
65 changes: 58 additions & 7 deletions firmware/quadruna/VC/src/io/io_imu.c
philam2001 marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
#include <math.h>
#include <stdio.h>

// Default sensitivity for LSM6DSM is 0.061 mg/digit
const float SENSITIVITY = 0.061f;
// Default accelerometer sensitivity for LSM6DSM is 0.061 mg/digit
const float ACCEL_SENSITIVITY = 0.061f;
philam2001 marked this conversation as resolved.
Show resolved Hide resolved
// Default gyroscope sensitivity for LSM6DSM is 8.75 mdeg/digit
const float GYRO_SENSITIVITY = 8.75f;

extern I2C_HandleTypeDef hi2c2;
static I2cInterface imu = { .i2c_handle = &hi2c2, .target_address = 0x6B, .timeout_ms = 100 };
Expand All @@ -13,8 +15,9 @@ bool io_imu_init()
{
if (hw_i2c_isTargetReady(&imu))
{
uint8_t buffer = 0x40; // turn on accelerometer to normal mode
return hw_i2c_memWrite(&imu, 0x10, &buffer, 1);
uint8_t buffer = 0x40; // turn on accelerometer/gyroscope to normal mode
bool activated_imu_sensors = hw_i2c_memWrite(&imu, 0x10, &buffer, 1) && hw_i2c_memWrite(&imu, 0x11, &buffer, 1);
return activated_imu_sensors;
}
return false;
}
Expand All @@ -31,7 +34,7 @@ bool io_imu_getLinearAccelerationX(float *x_acceleration)

// Convert raw value to acceleration in m/s^2
int16_t x_raw = (int16_t)(x_data[1] << 8 | x_data[0]);
*x_acceleration = x_raw * SENSITIVITY * 9.81f / 1000.0f;
*x_acceleration = x_raw * ACCEL_SENSITIVITY * 9.81f / 1000.0f;
philam2001 marked this conversation as resolved.
Show resolved Hide resolved
return true;
}

Expand All @@ -47,7 +50,7 @@ bool io_imu_getLinearAccelerationY(float *y_acceleration)

// Convert raw value to acceleration in m/s^2
int16_t y_raw = (int16_t)(y_data[1] << 8 | y_data[0]);
*y_acceleration = y_raw * SENSITIVITY * 9.81f / 1000.0f;
*y_acceleration = y_raw * ACCEL_SENSITIVITY * 9.81f / 1000.0f;
return true;
}

Expand All @@ -63,6 +66,54 @@ bool io_imu_getLinearAccelerationZ(float *z_acceleration)

// Convert raw value to acceleration in m/s^2 and subtract force of gravity
int16_t z_raw = (int16_t)(z_data[1] << 8 | z_data[0]);
*z_acceleration = z_raw * SENSITIVITY * 9.81f / 1000.0f - 9.81f;
*z_acceleration = z_raw * ACCEL_SENSITIVITY * 9.81f / 1000.0f - 9.81f;
return true;
}

bool io_imu_getAngularVelocityRoll(float *roll_velocity)
{
uint8_t roll_data[2];
bool is_read_successful = hw_i2c_memRead(&imu, 0x22, roll_data, 2);

if (!is_read_successful)
{
return false;
}

// Convert raw value to angular velocity (degrees per second or radians per second as required)
int16_t roll_raw = (int16_t)(roll_data[1] << 8 | roll_data[0]);
*roll_velocity = roll_raw * GYRO_SENSITIVITY / 1000.0f;
return true;
}

bool io_imu_getAngularVelocityPitch(float *pitch_velocity)
{
uint8_t pitch_data[2];
bool is_read_successful = hw_i2c_memRead(&imu, 0x24, pitch_data, 2);

if (!is_read_successful)
{
return false;
}

// Convert raw value to angular velocity (degrees per second or radians per second as required)
int16_t pitch_raw = (int16_t)(pitch_data[1] << 8 | pitch_data[0]);
*pitch_velocity = pitch_raw * GYRO_SENSITIVITY / 1000.0f;
return true;
}

bool io_imu_getAngularVelocityYaw(float *yaw_velocity)
{
uint8_t yaw_data[2];
bool is_read_successful = hw_i2c_memRead(&imu, 0x26, yaw_data, 2);

if (!is_read_successful)
{
return false;
}

// Convert raw value to angular velocity (degrees per second or radians per second as required)
int16_t yaw_raw = (int16_t)(yaw_data[1] << 8 | yaw_data[0]);
*yaw_velocity = yaw_raw * GYRO_SENSITIVITY / 1000.0f;
return true;
}
21 changes: 21 additions & 0 deletions firmware/quadruna/VC/src/io/io_imu.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,24 @@ bool io_imu_getLinearAccelerationY(float *y_acceleration);
* @return if successful read
*/
bool io_imu_getLinearAccelerationZ(float *z_acceleration);

/**
* @brief Gets the angular velocity in the roll direction
* @param roll_velocity Pointer to store the roll angular velocity
* @return True if the read is successful, false otherwise
*/
bool io_imu_getAngularVelocityRoll(float *roll_velocity);

/**
* @brief Gets the angular velocity in the pitch direction
* @param pitch_velocity Pointer to store the pitch angular velocity
* @return True if the read is successful, false otherwise
*/
bool io_imu_getAngularVelocityPitch(float *pitch_velocity);

/**
* @brief Gets the angular velocity in the yaw direction
* @param yaw_velocity Pointer to store the yaw angular velocity
* @return True if the read is successful, false otherwise
*/
bool io_imu_getAngularVelocityYaw(float *yaw_velocity);
25 changes: 9 additions & 16 deletions firmware/quadruna/VC/src/io/io_sbgEllipse.c
philam2001 marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
#include "sbgECom.h"
#include "interfaces/sbgInterfaceSerial.h"
#include "app_canTx.h"
#include "app_canUtils.h"

#include "io_time.h"
#include "io_log.h"

Expand Down Expand Up @@ -211,23 +213,9 @@ static void io_sbgEllipse_processMsg_status(const SbgBinaryLogData *log_data)
static void io_sbgEllipse_processMsg_EkfNavVelandPos(const SbgBinaryLogData *log_data)
{
// TODO: uncomment after initial testing, if this occurs skip reading data
// app_canAlerts_VC_Fault_SBGModeFault_set(sbgEComLogEkfGetSolutionMode(log_data->ekfNavData.status) !=
// SBG_ECOM_SOL_MODE_NAV_POSITION);

app_canTx_VC_EkfSolutionMode_set((VcEkfStatus)sbgEComLogEkfGetSolutionMode(log_data->ekfNavData.status));
philam2001 marked this conversation as resolved.
Show resolved Hide resolved

// uint32_t status = log_data->ekfNavData.status;

// if (sbgEComLogEkfGetSolutionMode(log_data->ekfNavData.status) != SBG_ECOM_SOL_MODE_NAV_POSITION)
// {
// uint32_t status = log_data->ekfNavData.status;

// bool is_velocity_valid = (status & SBG_ECOM_SOL_VELOCITY_VALID) != 0;
// bool is_position_valid = (status & SBG_ECOM_SOL_POSITION_VALID) != 0;

// if (!is_velocity_valid & !is_position_valid)
// return;
// }
// obtaining ekf solution mode from sbg ellipse and setting it in status field
sensor_data.ekf_solution_status = sbgEComLogEkfGetSolutionMode(log_data->ekfNavData.status);

// velocity data in m/s
sensor_data.ekf_nav_data.velocity.north = log_data->ekfNavData.velocity[0];
Expand Down Expand Up @@ -318,6 +306,11 @@ uint32_t io_sbgEllipse_getOverflowCount(void)
return sbg_queue_overflow_count;
}

uint32_t io_sbgEllipse_getEkfSolutionMode(void)
{
return sensor_data.ekf_solution_status;
philam2001 marked this conversation as resolved.
Show resolved Hide resolved
}

Vector3 *io_sbgEllipse_getImuAccelerations()
{
return &sensor_data.imu_data.acceleration;
Expand Down
7 changes: 7 additions & 0 deletions firmware/quadruna/VC/src/io/io_sbgEllipse.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ typedef struct
EkfEulerPacketData ekf_euler_data;
StatusPacketData status_data;
EkfNavPacketData ekf_nav_data;
uint32_t ekf_solution_status;
} SensorData;

#ifdef TARGET_EMBEDDED
Expand Down Expand Up @@ -114,6 +115,12 @@ uint32_t io_sbgEllipse_getComStatus(void);
*/
uint32_t io_sbgEllipse_getOverflowCount(void);

/*
* Get EKF Solution Mode Status
* @return the ekf solution mode
*/
uint32_t io_sbgEllipse_getEkfSolutionMode(void);

/**
* Get the IMU accelerations as a struct pointer with fields:
* - float x: Forward acceleration in m/s^2
Expand Down
Loading
Loading