Something went wrong on our end
control_algorithm.c 21.38 KiB
/*
* control_algorithm.c
*
* Created on: Feb 20, 2016
* Author: ucart
*/
// This implemented modular quadrotor software implements a PID control algorithm
#include "control_algorithm.h"
#include "graph_blocks.h"
#include "PID.h"
#include "util.h"
#include "timer.h"
//#define USE_LIDAR
#define ROLL_PITCH_MAX_ANGLE 0.35 // 20 degrees
#define PWM_DIFF_BOUNDS 20000
#define VRPN_REFRESH_TIME 0.01f // 10ms
void connect_autonomous(parameter_t* ps) {
struct computation_graph* graph = ps->graph;
//graph_set_source(graph, ps->pitch_pid, PID_SETPOINT, ps->x_pos_pid, PID_CORRECTION);
//graph_set_source(graph, ps->roll_pid, PID_SETPOINT, ps->y_pos_pid, PID_CORRECTION);
graph_set_source(graph, ps->pitch_pid, PID_SETPOINT, ps->yaw_correction, ROT_OUT_X);
graph_set_source(graph, ps->roll_pid, PID_SETPOINT, ps->yaw_correction, ROT_OUT_Y);
graph_set_source(graph, ps->mixer, MIXER_THROTTLE, ps->throttle_trim_add, ADD_SUM);
graph_set_source(graph, ps->yaw_r_pid, PID_SETPOINT, ps->yaw_pid, PID_CORRECTION);
}
void connect_manual(parameter_t* ps) {
struct computation_graph* graph = ps->graph;
graph_set_source(graph, ps->pitch_pid, PID_SETPOINT, ps->rc_pitch, CONST_VAL);
graph_set_source(graph, ps->roll_pid, PID_SETPOINT, ps->rc_roll, CONST_VAL);
graph_set_source(graph, ps->mixer, MIXER_THROTTLE, ps->rc_throttle, CONST_VAL);
graph_set_source(graph, ps->yaw_r_pid, PID_SETPOINT, ps->rc_yaw, CONST_VAL);
}
int control_algorithm_init(parameter_t * ps)
{
struct computation_graph* graph = create_graph();
ps->graph = graph;
// Create all the PID blocks
ps->roll_pid = graph_add_defined_block(graph, BLOCK_PID, "Roll PID");
ps->pitch_pid = graph_add_defined_block(graph, BLOCK_PID, "Pitch PID");
ps->yaw_pid = graph_add_defined_block(graph, BLOCK_PID, "Yaw PID");
ps->roll_r_pid = graph_add_defined_block(graph, BLOCK_PID, "Roll Rate PID");
ps->pitch_r_pid = graph_add_defined_block(graph, BLOCK_PID, "Pitch Rate PID");
ps->yaw_r_pid = graph_add_defined_block(graph, BLOCK_PID, "Yaw Rate PID");
ps->x_pos_pid = graph_add_defined_block(graph, BLOCK_PID, "X pos PID");
ps->y_pos_pid = graph_add_defined_block(graph, BLOCK_PID, "Y pos PID");
ps->alt_pid = graph_add_defined_block(graph, BLOCK_PID, "Altitude PID");
ps->x_set = graph_add_defined_block(graph, BLOCK_CONSTANT, "X Setpoint"); // ID 9
ps->y_set = graph_add_defined_block(graph, BLOCK_CONSTANT, "Y Setpoint");
ps->alt_set = graph_add_defined_block(graph, BLOCK_CONSTANT, "Alt Setpoint");
ps->yaw_set = graph_add_defined_block(graph, BLOCK_CONSTANT, "Yaw Setpoint");
ps->throttle_trim = graph_add_defined_block(graph, BLOCK_CONSTANT, "Throttle trim");
ps->throttle_trim_add = graph_add_defined_block(graph, BLOCK_ADD, "T trim add");
// Create blocks for sensor inputs
ps->cur_pitch = graph_add_defined_block(graph, BLOCK_CONSTANT, "Pitch"); // ID 15
ps->cur_roll = graph_add_defined_block(graph, BLOCK_CONSTANT, "Roll");
ps->cur_yaw = graph_add_defined_block(graph, BLOCK_CONSTANT, "Yaw");
ps->lidar = graph_add_defined_block(graph, BLOCK_CONSTANT, "Lidar");
ps->flow_vel_x = graph_add_defined_block(graph, BLOCK_CONSTANT, "Flow Vel X");
ps->flow_vel_y = graph_add_defined_block(graph, BLOCK_CONSTANT, "Flow Vel y");
ps->flow_quality = graph_add_defined_block(graph, BLOCK_CONSTANT, "Flow Quality");
// Sensor trims
ps->pitch_trim = graph_add_defined_block(graph, BLOCK_CONSTANT, "Pitch trim");
ps->pitch_trim_add = graph_add_defined_block(graph, BLOCK_ADD, "Pitch trim add");
// Yaw angular velocity PID
ps->gyro_y = graph_add_defined_block(graph, BLOCK_CONSTANT, "Gyro Y");
ps->gyro_x = graph_add_defined_block(graph, BLOCK_CONSTANT, "Gyro X");
ps->gyro_z = graph_add_defined_block(graph, BLOCK_CONSTANT, "Gyro Z");
ps->clamp_d_pwmP = graph_add_defined_block(graph, BLOCK_BOUNDS, "P PWM Clamp");
ps->clamp_d_pwmR = graph_add_defined_block(graph, BLOCK_BOUNDS, "R PWM Clamp");
ps->clamp_d_pwmY = graph_add_defined_block(graph, BLOCK_BOUNDS, "Y PWM Clamp");
// Create blocks for VRPN data
ps->vrpn_x = graph_add_defined_block(graph, BLOCK_CONSTANT, "VRPN X");
ps->vrpn_y = graph_add_defined_block(graph, BLOCK_CONSTANT, "VRPN Y");
ps->vrpn_alt = graph_add_defined_block(graph, BLOCK_CONSTANT, "VRPN Alt");
ps->vrpn_pitch = graph_add_defined_block(graph, BLOCK_CONSTANT, "VRPN Pitch");
ps->vrpn_roll = graph_add_defined_block(graph, BLOCK_CONSTANT, "VRPN Roll");
// Create blocks for RC controller
ps->rc_pitch = graph_add_defined_block(graph, BLOCK_CONSTANT, "RC Pitch");
ps->rc_roll = graph_add_defined_block(graph, BLOCK_CONSTANT, "RC Roll");
ps->rc_yaw = graph_add_defined_block(graph, BLOCK_CONSTANT, "RC Yaw");
ps->rc_throttle = graph_add_defined_block(graph, BLOCK_CONSTANT, "RC Throttle");
// Create blocks for velocity controllers
ps->x_vel_pid = graph_add_defined_block(graph, BLOCK_PID, "X Vel PID");
ps->y_vel_pid = graph_add_defined_block(graph, BLOCK_PID, "Y Vel PID");
ps->x_vel = graph_add_defined_block(graph, BLOCK_PID, "X Vel");
ps->y_vel = graph_add_defined_block(graph, BLOCK_PID, "Y Vel");
ps->x_vel_clamp = graph_add_defined_block(graph, BLOCK_BOUNDS, "X Vel Clamp");
ps->y_vel_clamp = graph_add_defined_block(graph, BLOCK_BOUNDS, "Y vel Clamp");
// Converts global X/Y to local X/Y
ps->yaw_correction = graph_add_defined_block(graph, BLOCK_YAW_ROT, "Yaw Correction");
ps->mixer = graph_add_defined_block(graph, BLOCK_MIXER, "Signal Mixer");
ps->angle_time = graph_add_defined_block(graph, BLOCK_CONSTANT, "Ts_IMU");
ps->pos_time = graph_add_defined_block(graph, BLOCK_CONSTANT, "Ts_VRPN");
// Useful zero block
int zero_block = graph_add_defined_block(graph, BLOCK_CONSTANT, "zero");
graph_set_param_val(graph, zero_block, CONST_SET, 0);
// Connect pitch PID chain
// Trims
graph_set_source(graph, ps->pitch_trim_add, ADD_SUMMAND1, ps->pitch_trim, CONST_VAL);
graph_set_source(graph, ps->pitch_trim_add, ADD_SUMMAND2, ps->cur_pitch, CONST_VAL);
// Controllers
graph_set_source(graph, ps->pitch_r_pid, PID_SETPOINT, ps->pitch_pid, PID_CORRECTION);
graph_set_source(graph, ps->pitch_r_pid, PID_CUR_POINT, ps->gyro_y, CONST_VAL);
graph_set_source(graph, ps->pitch_r_pid, PID_DT, ps->angle_time, CONST_VAL);
graph_set_source(graph, ps->pitch_pid, PID_CUR_POINT, ps->pitch_trim_add, ADD_SUM);
//graph_set_source(graph, ps->pitch_pid, PID_CUR_POINT, ps->vrpn_pitch, CONST_VAL);
graph_set_source(graph, ps->pitch_pid, PID_DT, ps->angle_time, CONST_VAL);
// Connect roll PID chain
graph_set_source(graph, ps->roll_r_pid, PID_SETPOINT, ps->roll_pid, PID_CORRECTION);
graph_set_source(graph, ps->roll_r_pid, PID_CUR_POINT, ps->gyro_x, CONST_VAL);
graph_set_source(graph, ps->roll_r_pid, PID_DT, ps->angle_time, CONST_VAL);
graph_set_source(graph, ps->roll_pid, PID_CUR_POINT, ps->cur_roll, CONST_VAL);
//graph_set_source(graph, ps->roll_pid, PID_CUR_POINT, ps->vrpn_roll, CONST_VAL);
graph_set_source(graph, ps->roll_pid, PID_DT, ps->angle_time, CONST_VAL);
// Connect yaw PID chain
graph_set_source(graph, ps->yaw_r_pid, PID_SETPOINT, ps->rc_yaw, PID_CORRECTION);
graph_set_source(graph, ps->yaw_r_pid, PID_CUR_POINT, ps->gyro_z, CONST_VAL);
graph_set_source(graph, ps->yaw_r_pid, PID_DT, ps->angle_time, CONST_VAL);
// X velocity PID
// Use a PID block to compute the derivative
graph_set_param_val(graph, ps->x_vel, PID_KD, -1);
graph_set_source(graph, ps->x_vel, PID_DT, ps->pos_time, CONST_VAL);
graph_set_source(graph, ps->x_vel, PID_CUR_POINT, ps->vrpn_x, CONST_VAL);
graph_set_source(graph, ps->x_vel, PID_SETPOINT, zero_block, CONST_VAL);
// Connect velocity PID itself
graph_set_source(graph, ps->x_vel_pid, PID_DT, ps->pos_time, CONST_VAL);
graph_set_source(graph, ps->x_vel_pid, PID_CUR_POINT, ps->x_vel, PID_CORRECTION);
graph_set_source(graph, ps->x_vel_pid, PID_SETPOINT, ps->x_vel_clamp, BOUNDS_OUT);
graph_set_source(graph, ps->x_vel_clamp, BOUNDS_IN, ps->x_pos_pid, PID_CORRECTION);
// X/Y global to local conversion
graph_set_source(graph, ps->yaw_correction, ROT_YAW, ps->cur_yaw, CONST_VAL);
graph_set_source(graph, ps->yaw_correction, ROT_CUR_X, ps->x_vel_pid, PID_CORRECTION);
graph_set_source(graph, ps->yaw_correction, ROT_CUR_Y, ps->y_vel_pid, PID_CORRECTION);
// Y velocity PID
// Use a PID block to compute the derivative
graph_set_param_val(graph, ps->y_vel, PID_KD, -1);
graph_set_source(graph, ps->y_vel, PID_DT, ps->pos_time, CONST_VAL);
graph_set_source(graph, ps->y_vel, PID_CUR_POINT, ps->vrpn_y, CONST_VAL);
graph_set_source(graph, ps->y_vel, PID_SETPOINT, zero_block, CONST_VAL);
// Connect velocity PID itself
graph_set_source(graph, ps->y_vel_pid, PID_DT, ps->pos_time, CONST_VAL);
graph_set_source(graph, ps->y_vel_pid, PID_CUR_POINT, ps->y_vel, PID_CORRECTION);
graph_set_source(graph, ps->y_vel_pid, PID_SETPOINT, ps->y_vel_clamp, BOUNDS_OUT);
graph_set_source(graph, ps->y_vel_clamp, BOUNDS_IN, ps->y_pos_pid, PID_CORRECTION);
// X position
graph_set_source(graph, ps->x_pos_pid, PID_DT, ps->pos_time, CONST_VAL);
graph_set_source(graph, ps->x_pos_pid, PID_CUR_POINT, ps->vrpn_x, CONST_VAL);
graph_set_source(graph, ps->x_pos_pid, PID_SETPOINT, ps->x_set, CONST_VAL);
// Y position
graph_set_source(graph, ps->y_pos_pid, PID_DT, ps->pos_time, CONST_VAL);
graph_set_source(graph, ps->y_pos_pid, PID_CUR_POINT, ps->vrpn_y, CONST_VAL);
graph_set_source(graph, ps->y_pos_pid, PID_SETPOINT, ps->y_set, CONST_VAL);
// Alt autonomous
#ifdef USE_LIDAR
graph_set_source(graph, ps->alt_pid, PID_DT, ps->angle_time, CONST_VAL);
graph_set_source(graph, ps->alt_pid, PID_CUR_POINT, ps->lidar, CONST_VAL);
#else
graph_set_source(graph, ps->alt_pid, PID_DT, ps->pos_time, CONST_VAL);
graph_set_source(graph, ps->alt_pid, PID_CUR_POINT, ps->vrpn_alt, CONST_VAL);
#endif
graph_set_source(graph, ps->alt_pid, PID_SETPOINT, ps->alt_set, CONST_VAL);
graph_set_source(graph, ps->throttle_trim_add, ADD_SUMMAND1, ps->alt_pid, PID_CORRECTION);
graph_set_source(graph, ps->throttle_trim_add, ADD_SUMMAND2, ps->throttle_trim, CONST_VAL);
// Yaw angle
graph_set_source(graph, ps->yaw_pid, PID_DT, ps->pos_time, CONST_VAL);
graph_set_source(graph, ps->yaw_pid, PID_SETPOINT, ps->yaw_set, CONST_VAL);
graph_set_source(graph, ps->yaw_pid, PID_CUR_POINT, ps->cur_yaw, CONST_VAL);
// Connect PWM clamping blocks
graph_set_source(graph, ps->clamp_d_pwmP, BOUNDS_IN, ps->pitch_r_pid, PID_CORRECTION);
graph_set_source(graph, ps->clamp_d_pwmR, BOUNDS_IN, ps->roll_r_pid, PID_CORRECTION);
graph_set_source(graph, ps->clamp_d_pwmY, BOUNDS_IN, ps->yaw_r_pid, PID_CORRECTION);
// Connect signal mixer
//graph_set_source(graph, ps->mixer, MIXER_THROTTLE, ps->rc_throttle, CONST_VAL);
graph_set_source(graph, ps->mixer, MIXER_PITCH, ps->clamp_d_pwmP, BOUNDS_OUT);
graph_set_source(graph, ps->mixer, MIXER_ROLL, ps->clamp_d_pwmR, BOUNDS_OUT);
graph_set_source(graph, ps->mixer, MIXER_YAW, ps->clamp_d_pwmY, BOUNDS_OUT);
// Set pitch PID constants
graph_set_param_val(graph, ps->pitch_pid, PID_KP, PITCH_ANGLE_KP);
graph_set_param_val(graph, ps->pitch_pid, PID_KI, PITCH_ANGLE_KI);
graph_set_param_val(graph, ps->pitch_pid, PID_KD, PITCH_ANGLE_KD);
graph_set_param_val(graph, ps->pitch_pid, PID_ALPHA, PITCH_ANGLE_ALPHA);
graph_set_param_val(graph, ps->pitch_r_pid, PID_KP, PITCH_ANGULAR_VELOCITY_KP);
graph_set_param_val(graph, ps->pitch_r_pid, PID_KI, PITCH_ANGULAR_VELOCITY_KI);
graph_set_param_val(graph, ps->pitch_r_pid, PID_KD, PITCH_ANGULAR_VELOCITY_KD);
graph_set_param_val(graph, ps->pitch_r_pid, PID_ALPHA, PITCH_ANGULAR_VELOCITY_ALPHA);
// Set roll PID constants
graph_set_param_val(graph, ps->roll_pid, PID_KP, ROLL_ANGLE_KP);
graph_set_param_val(graph, ps->roll_pid, PID_KI, ROLL_ANGLE_KI);
graph_set_param_val(graph, ps->roll_pid, PID_KD, ROLL_ANGLE_KD);
graph_set_param_val(graph, ps->roll_pid, PID_ALPHA, ROLL_ANGLE_ALPHA);
graph_set_param_val(graph, ps->roll_r_pid, PID_KP, ROLL_ANGULAR_VELOCITY_KP);
graph_set_param_val(graph, ps->roll_r_pid, PID_KI, ROLL_ANGULAR_VELOCITY_KI);
graph_set_param_val(graph, ps->roll_r_pid, PID_KD, ROLL_ANGULAR_VELOCITY_KD);
graph_set_param_val(graph, ps->roll_r_pid, PID_ALPHA, ROLL_ANGULAR_VELOCITY_ALPHA);
// Set yaw PID constants
graph_set_param_val(graph, ps->yaw_pid, PID_KP, YAW_ANGLE_KP);
graph_set_param_val(graph, ps->yaw_pid, PID_KI, YAW_ANGLE_KI);
graph_set_param_val(graph, ps->yaw_pid, PID_KD, YAW_ANGLE_KD);
graph_set_param_val(graph, ps->yaw_r_pid, PID_KP, YAW_ANGULAR_VELOCITY_KP);
graph_set_param_val(graph, ps->yaw_r_pid, PID_KI, YAW_ANGULAR_VELOCITY_KI);
graph_set_param_val(graph, ps->yaw_r_pid, PID_KD, YAW_ANGULAR_VELOCITY_KD);
// Set velocity constants
graph_set_param_val(graph, ps->x_vel_pid, PID_KP, XVEL_KP);
graph_set_param_val(graph, ps->x_vel_pid, PID_KD, XVEL_KD);
graph_set_param_val(graph, ps->y_vel_pid, PID_KP, YVEL_KP);
graph_set_param_val(graph, ps->y_vel_pid, PID_KD, YVEL_KD);
// Differentiators
graph_set_param_val(graph, ps->x_vel, PID_ALPHA, XVEL_ALPHA);
graph_set_param_val(graph, ps->y_vel, PID_ALPHA, YVEL_ALPHA);
// Set X/Y/Alt constants
graph_set_param_val(graph, ps->x_pos_pid, PID_KP, XPOS_KP);
graph_set_param_val(graph, ps->x_pos_pid, PID_KI, XPOS_KI);
graph_set_param_val(graph, ps->x_pos_pid, PID_KD, XPOS_KD);
graph_set_param_val(graph, ps->x_pos_pid, PID_ALPHA, XPOS_ALPHA);
graph_set_param_val(graph, ps->y_pos_pid, PID_KP, YPOS_KP);
graph_set_param_val(graph, ps->y_pos_pid, PID_KI, YPOS_KI);
graph_set_param_val(graph, ps->y_pos_pid, PID_KD, YPOS_KD);
graph_set_param_val(graph, ps->y_pos_pid, PID_ALPHA, YPOS_ALPHA);
graph_set_param_val(graph, ps->alt_pid, PID_KP, ALT_ZPOS_KP);
graph_set_param_val(graph, ps->alt_pid, PID_KI, ALT_ZPOS_KI);
graph_set_param_val(graph, ps->alt_pid, PID_KD, ALT_ZPOS_KD);
graph_set_param_val(graph, ps->alt_pid, PID_ALPHA, ALT_ZPOS_ALPHA);
// Set PWM difference clamping limits
graph_set_param_val(graph, ps->clamp_d_pwmP, BOUNDS_MIN, -PWM_DIFF_BOUNDS);
graph_set_param_val(graph, ps->clamp_d_pwmP, BOUNDS_MAX, PWM_DIFF_BOUNDS);
graph_set_param_val(graph, ps->clamp_d_pwmR, BOUNDS_MIN, -PWM_DIFF_BOUNDS);
graph_set_param_val(graph, ps->clamp_d_pwmR, BOUNDS_MAX, PWM_DIFF_BOUNDS);
graph_set_param_val(graph, ps->clamp_d_pwmY, BOUNDS_MIN, -PWM_DIFF_BOUNDS);
graph_set_param_val(graph, ps->clamp_d_pwmY, BOUNDS_MAX, PWM_DIFF_BOUNDS);
// Set velocity clamping limits
graph_set_param_val(graph, ps->x_vel_clamp, BOUNDS_MIN, -VEL_CLAMP);
graph_set_param_val(graph, ps->x_vel_clamp, BOUNDS_MAX, VEL_CLAMP);
graph_set_param_val(graph, ps->y_vel_clamp, BOUNDS_MIN, -VEL_CLAMP);
graph_set_param_val(graph, ps->y_vel_clamp, BOUNDS_MAX, VEL_CLAMP);
// Set trims
graph_set_param_val(graph, ps->pitch_trim, CONST_SET, PITCH_TRIM);
// Initial value for sampling periods
graph_set_param_val(graph, ps->pos_time, CONST_SET, 0.04);
graph_set_param_val(graph, ps->angle_time, CONST_SET, 0.005);
// Set initial mode
connect_manual(ps);
return 0;
}
int control_algorithm(log_t* log_struct, user_input_t * user_input_struct, sensor_t* sensor_struct, setpoint_t* setpoint_struct, parameter_t* ps, user_defined_t* user_defined_struct, actuator_command_t* actuator_struct, modular_structs_t* structs)
{
struct computation_graph* graph = ps->graph;
// use the 'flap' switch as the flight mode selector
int cur_fm_switch = read_flap(user_input_struct->rc_commands[FLAP]);
static int last_fm_switch = MANUAL_FLIGHT_MODE;
// reset flight_mode to MANUAL right away if the flap switch is in manual position
// to engage AUTO mode the code waits for a new packet after the flap is switched to auto
// before actually engaging AUTO mode
if(cur_fm_switch == MANUAL_FLIGHT_MODE) {
if (last_fm_switch == AUTO_FLIGHT_MODE) {
connect_manual(ps);
}
user_defined_struct->flight_mode = MANUAL_FLIGHT_MODE;
}
// flap switch was just toggled to auto flight mode
if((last_fm_switch != cur_fm_switch) && (cur_fm_switch == AUTO_FLIGHT_MODE))
{
user_defined_struct->engaging_auto = 1;
graph_set_param_val(graph, ps->throttle_trim, CONST_SET, user_input_struct->rc_commands[THROTTLE]);
}
if(user_input_struct->locationFresh && user_defined_struct->engaging_auto == 1)
user_defined_struct->engaging_auto = 2;
// The last packet ID from VRPN.
static int last_vrpn_id = 0;
// if the flap switch was toggled to AUTO_FLIGHT_MODE and we've received a new packet
// then record the current position as the desired position
// also reset the previous error and accumulated error from the position PIDs
if((cur_fm_switch == AUTO_FLIGHT_MODE) && (user_defined_struct->engaging_auto == 2))
{
graph_set_param_val(graph, ps->x_set, CONST_SET, sensor_struct->currentQuadPosition.x_pos);
graph_set_param_val(graph, ps->y_set, CONST_SET, sensor_struct->currentQuadPosition.y_pos);
graph_set_param_val(graph, ps->alt_set, CONST_SET, sensor_struct->currentQuadPosition.alt_pos);
graph_set_param_val(graph, ps->yaw_set, CONST_SET, sensor_struct->currentQuadPosition.yaw);
// reset the flag that engages auto mode
user_defined_struct->engaging_auto = 0;
// finally engage the AUTO_FLIGHT_MODE
// this ensures that we've gotten a new update packet right after the switch was set to auto mode
user_defined_struct->flight_mode = AUTO_FLIGHT_MODE;
connect_autonomous(ps);
// Reset this when autonomous is engaged, so there is not a large difference at the start of autonomous
last_vrpn_id = sensor_struct->currentQuadPosition.packetId - 1;
}
//PIDS///////////////////////////////////////////////////////////////////////
/* Position loop
* Reads current position, and outputs
* a pitch or roll for the angle loop PIDs
*/
if(user_input_struct->locationFresh)
{
// VRPN values
graph_set_param_val(graph, ps->vrpn_x, CONST_SET, sensor_struct->currentQuadPosition.x_pos);
graph_set_param_val(graph, ps->vrpn_y, CONST_SET, sensor_struct->currentQuadPosition.y_pos);
graph_set_param_val(graph, ps->vrpn_alt, CONST_SET, sensor_struct->currentQuadPosition.alt_pos);
graph_set_param_val(graph, ps->vrpn_pitch, CONST_SET, sensor_struct->currentQuadPosition.pitch);
graph_set_param_val(graph, ps->vrpn_roll, CONST_SET, sensor_struct->currentQuadPosition.roll);
graph_set_param_val(graph, ps->cur_yaw, CONST_SET, sensor_struct->currentQuadPosition.yaw);
// Use the difference in IDs to compute the sampling time for the position PIDs
int current_vrpn_id = sensor_struct->currentQuadPosition.packetId;
graph_set_param_val(graph, ps->pos_time, CONST_SET, VRPN_REFRESH_TIME * (current_vrpn_id - last_vrpn_id));
last_vrpn_id = current_vrpn_id;
}
// Loop time
graph_set_param_val(graph, ps->angle_time, CONST_SET, get_last_loop_time());
// Sensor values
graph_set_param_val(graph, ps->cur_pitch, CONST_SET, sensor_struct->pitch_angle_filtered);
graph_set_param_val(graph, ps->cur_roll, CONST_SET, sensor_struct->roll_angle_filtered);
graph_set_param_val(graph, ps->gyro_y, CONST_SET, sensor_struct->gyr_y);
graph_set_param_val(graph, ps->gyro_x, CONST_SET, sensor_struct->gyr_x);
graph_set_param_val(graph, ps->gyro_z, CONST_SET, sensor_struct->gyr_z);
graph_set_param_val(graph, ps->lidar, CONST_SET, sensor_struct->lidar_altitude);
// RC values
graph_set_param_val(graph, ps->rc_pitch, CONST_SET, user_input_struct->pitch_angle_manual_setpoint);
graph_set_param_val(graph, ps->rc_roll, CONST_SET, user_input_struct->roll_angle_manual_setpoint);
graph_set_param_val(graph, ps->rc_yaw, CONST_SET, user_input_struct->yaw_manual_setpoint);
graph_set_param_val(graph, ps->rc_throttle, CONST_SET, user_input_struct->rc_commands[THROTTLE]);
// Compute VRPN blocks so they can be logged
int outputs[5] = {ps->mixer, ps->vrpn_alt, ps->vrpn_pitch, ps->vrpn_roll, ps->lidar};
graph_compute_nodes(graph, outputs, 5);
// here for now so in case any flight command is not PID controlled, it will default to rc_command value:
//memcpy(raw_actuator_struct->controller_corrected_motor_commands, user_input_struct->rc_commands, sizeof(int) * 6);
// don't use the PID corrections if the throttle is less than about 10% of its range
// unless we are in autonomous
if((user_input_struct->rc_commands[THROTTLE] > 0.18000) ||
user_defined_struct->flight_mode == AUTO_FLIGHT_MODE)
{
//THROTTLE
actuator_struct->motor_magnitudes[0] = graph_get_output(graph, ps->mixer, MIXER_MOTOR0);
actuator_struct->motor_magnitudes[1] = graph_get_output(graph, ps->mixer, MIXER_MOTOR1);
actuator_struct->motor_magnitudes[2] = graph_get_output(graph, ps->mixer, MIXER_MOTOR2);
actuator_struct->motor_magnitudes[3] = graph_get_output(graph, ps->mixer, MIXER_MOTOR3);
}
else
{
actuator_struct->motor_magnitudes[0] = user_input_struct->rc_commands[THROTTLE];
actuator_struct->motor_magnitudes[1] = user_input_struct->rc_commands[THROTTLE];
actuator_struct->motor_magnitudes[2] = user_input_struct->rc_commands[THROTTLE];
actuator_struct->motor_magnitudes[3] = user_input_struct->rc_commands[THROTTLE];
}
last_fm_switch = cur_fm_switch;
// Make location stale now
user_input_struct->locationFresh = 0;
return 0;
}
void setPIDCoeff(PID_t* p, float pValue, float iValue, float dValue) {
p->Kp = pValue;
p->Ki = iValue;
p->Kd = dValue;
}