|
|
|
|
@ -14,7 +14,7 @@
|
|
|
|
|
#define MC_TASK_STACK_SIZE 2048
|
|
|
|
|
|
|
|
|
|
// Like with the speed sensors, use a single-length queue as a way to safely copy data to another non-synchronised task
|
|
|
|
|
static xQueueHandle motor_settings_queue[3];
|
|
|
|
|
static xQueueHandle motor_control_queue[3];
|
|
|
|
|
static xQueueHandle motor_parameters_queue[3];
|
|
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
|
@ -32,7 +32,7 @@ const gpio_num_t motor_en_pins[3] = {GPIO_ROLLER1_EN, GPIO_ROLLER2_EN, GPIO_ROLL
|
|
|
|
|
|
|
|
|
|
static void motor_control_task(void *pvParameters) {
|
|
|
|
|
TickType_t xLastWakeTime;
|
|
|
|
|
motor_settings_t m_set;
|
|
|
|
|
motor_control_t m_ctrl;
|
|
|
|
|
motor_parameters_t m_param;
|
|
|
|
|
float actual_speed;
|
|
|
|
|
float error;
|
|
|
|
|
@ -44,14 +44,14 @@ static void motor_control_task(void *pvParameters) {
|
|
|
|
|
for (;;) {
|
|
|
|
|
|
|
|
|
|
for (int m_id = 0; m_id < 3; m_id++) {
|
|
|
|
|
// Get the latest motor settings and parameters
|
|
|
|
|
xQueuePeek(motor_settings_queue[m_id], &m_set, 0);
|
|
|
|
|
// Get the latest motor control and parameters
|
|
|
|
|
xQueuePeek(motor_control_queue[m_id], &m_ctrl, 0);
|
|
|
|
|
xQueuePeek(motor_parameters_queue[m_id], &m_param, 0);
|
|
|
|
|
|
|
|
|
|
if (m_set.enabled) {
|
|
|
|
|
if (m_ctrl.enabled) {
|
|
|
|
|
|
|
|
|
|
actual_speed = get_roller_speed(m_id);
|
|
|
|
|
error = m_set.desired_speed - actual_speed;
|
|
|
|
|
error = m_ctrl.desired_speed - actual_speed;
|
|
|
|
|
m_status[m_id].i_error += error * MC_ITERATION_TIME;
|
|
|
|
|
d_error = (error - m_status[m_id].last_error) / MC_ITERATION_TIME;
|
|
|
|
|
m_status[m_id].last_error = error;
|
|
|
|
|
@ -101,18 +101,18 @@ static void motor_control_task(void *pvParameters) {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void set_motor_settings(int motor_id, motor_settings_t new_settings) {
|
|
|
|
|
xQueueOverwrite(motor_settings_queue[motor_id], &new_settings);
|
|
|
|
|
void set_motor_control(int motor_id, motor_control_t new_control) {
|
|
|
|
|
xQueueOverwrite(motor_control_queue[motor_id], &new_control);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void set_motor_params(int motor_id, motor_parameters_t new_params) {
|
|
|
|
|
xQueueOverwrite(motor_parameters_queue[motor_id], &new_params);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
motor_settings_t get_motor_settings(int motor_id) {
|
|
|
|
|
motor_settings_t current_motor_settings;
|
|
|
|
|
xQueuePeek(motor_settings_queue[motor_id], ¤t_motor_settings, 0);
|
|
|
|
|
return current_motor_settings;
|
|
|
|
|
motor_control_t get_motor_control(int motor_id) {
|
|
|
|
|
motor_control_t current_motor_control;
|
|
|
|
|
xQueuePeek(motor_control_queue[motor_id], ¤t_motor_control, 0);
|
|
|
|
|
return current_motor_control;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
motor_parameters_t get_motor_parameters(int motor_id) {
|
|
|
|
|
@ -132,18 +132,18 @@ void motor_control_setup(void) {
|
|
|
|
|
|
|
|
|
|
for (int m_id = 0; m_id < 3; m_id++) {
|
|
|
|
|
// Allocate queues
|
|
|
|
|
motor_settings_queue[m_id] = xQueueCreate(1, sizeof(motor_settings_t));
|
|
|
|
|
motor_control_queue[m_id] = xQueueCreate(1, sizeof(motor_control_t));
|
|
|
|
|
motor_parameters_queue[m_id] = xQueueCreate(1, sizeof(motor_parameters_t));
|
|
|
|
|
motor_status_queue[m_id] = xQueueCreate(1, sizeof(motor_status_t));
|
|
|
|
|
|
|
|
|
|
// Prime queues - these are single item queues, and so functions reading from them just
|
|
|
|
|
// assume something is there.
|
|
|
|
|
// TODO - this is where we'd read in the saved motor params from flash.
|
|
|
|
|
motor_settings_t init_motor_settings;
|
|
|
|
|
motor_control_t init_motor_control;
|
|
|
|
|
motor_parameters_t init_motor_params;
|
|
|
|
|
motor_status_t blank_motor_status;
|
|
|
|
|
|
|
|
|
|
xQueueOverwrite(motor_settings_queue[m_id], &init_motor_settings);
|
|
|
|
|
xQueueOverwrite(motor_control_queue[m_id], &init_motor_control);
|
|
|
|
|
xQueueOverwrite(motor_parameters_queue[m_id], &init_motor_params);
|
|
|
|
|
xQueueOverwrite(motor_status_queue[m_id], &blank_motor_status);
|
|
|
|
|
}
|
|
|
|
|
|