diff --git a/quad/sw/modular_quad_pid/gen_diagram/Makefile b/quad/sw/modular_quad_pid/gen_diagram/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..610e289a0430678f42d41648f6c8f98143450b6a --- /dev/null +++ b/quad/sw/modular_quad_pid/gen_diagram/Makefile @@ -0,0 +1,10 @@ + +COMP_GRAPH = ../../../computation_graph +QUAD_BLOCKS = ../src/graph_blocks + +gen_diagram: generate.c + gcc -o gen_diagram -I. -I$(COMP_GRAPH)/src generate.c $(COMP_GRAPH)/src/computation_graph.c $(QUAD_BLOCKS)/node_bounds.c $(QUAD_BLOCKS)/node_pid.c $(QUAD_BLOCKS)/node_mixer.c + +.PHONY: clean +clean: + rm gen_diagram diff --git a/quad/sw/modular_quad_pid/gen_diagram/gen_diagram b/quad/sw/modular_quad_pid/gen_diagram/gen_diagram new file mode 100644 index 0000000000000000000000000000000000000000..ae1620225638cc42929390bc1646225a8b1cbbf3 Binary files /dev/null and b/quad/sw/modular_quad_pid/gen_diagram/gen_diagram differ diff --git a/quad/sw/modular_quad_pid/gen_diagram/generate.c b/quad/sw/modular_quad_pid/gen_diagram/generate.c new file mode 100644 index 0000000000000000000000000000000000000000..b7cc7966c71e37df5759f62aa0c6c6a938b94358 --- /dev/null +++ b/quad/sw/modular_quad_pid/gen_diagram/generate.c @@ -0,0 +1,185 @@ +#include <stdio.h> +#include "computation_graph.h" +#include "../src/graph_blocks/node_pid.h" +#include "../src/graph_blocks/node_bounds.h" +#include "graph_blocks/node_constant.h" +#include "../src/graph_blocks/node_mixer.h" +#include "local_PID.h" + +#define ROLL_PITCH_MAX_ANGLE 0.3490 // 20 degrees + +typedef struct parameter_t { + struct computation_graph* graph; + // PID blocks + int roll_pid; + int pitch_pid; + int yaw_pid; + int roll_r_pid; + int pitch_r_pid; + int yaw_r_pid; + int x_pos_pid; + int y_pos_pid; + int alt_pid; + // Sensor blocks + int cur_pitch; + int cur_roll; + int cur_yaw; + int theta_dot; + int phi_dot; + int psi_dot; + // RC blocks + int rc_pitch; + int rc_roll; + int rc_yaw; + int rc_throttle; + // Loop time + int dt; + // Signal mixer + int mixer; + // Clamping blocks + int clamp_pitch; + int clamp_roll; + int clamp_d_pwmR; // Clamp the change in PWM values for roll + int clamp_d_pwmP; // ... pitch + int clamp_d_pwmY; // ... yaw +} parameter_t; + +parameter_t ps; + + int control_algorithm_init(parameter_t * ps); + +int main() { + + FILE* dot_fp; + dot_fp = fopen(".\\network.dot", "w"); + export_dot(ps.graph, dot_fp); + fclose(dot_fp); +} + + + 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_node_pid(graph, "Roll PID"); + ps->pitch_pid = graph_add_node_pid(graph, "Pitch PID"); + ps->yaw_pid = graph_add_node_pid(graph, "Yaw PID"); + ps->roll_r_pid = graph_add_node_pid(graph, "Roll Rate PID"); + ps->pitch_r_pid = graph_add_node_pid(graph, "Pitch Rate PID"); + ps->yaw_r_pid = graph_add_node_pid(graph, "Yaw Rate PID"); + ps->x_pos_pid = graph_add_node_pid(graph, "X pos PID PID"); + ps->y_pos_pid = graph_add_node_pid(graph, "Y pos PID"); + ps->alt_pid = graph_add_node_pid(graph, "Altitude"); + + // Create blocks for bounds checking + ps->clamp_d_pwmP = graph_add_node_bounds(graph, "P PWM Clamp"); + ps->clamp_d_pwmR = graph_add_node_bounds(graph, "R PWM Clamp"); + ps->clamp_d_pwmY = graph_add_node_bounds(graph, "Y PWM Clamp"); + ps->clamp_pitch = graph_add_node_bounds(graph, "Pitch Clamp"); + ps->clamp_roll= graph_add_node_bounds(graph, "Roll Clamp"); + + // Create blocks for sensor inputs + ps->cur_pitch = graph_add_node_const(graph, "Pitch"); + ps->cur_roll = graph_add_node_const(graph, "Roll"); + ps->cur_yaw = graph_add_node_const(graph, "Yaw"); + // Yaw angular velocity PID + // theta_dot is the angular velocity about the y-axis + // phi_dot is the angular velocity about the x-axis + // psi_dot is the angular velocity about the z-axis + // These are calculated from using the gimbal equations + ps->theta_dot = graph_add_node_const(graph, "dTheta"); + ps->phi_dot = graph_add_node_const(graph, "dPhi"); + ps->psi_dot = graph_add_node_const(graph, "dPsi"); + + // Create blocks for RC controller + ps->rc_pitch = graph_add_node_const(graph, "RC Pitch"); + ps->rc_roll = graph_add_node_const(graph, "RC Roll"); + ps->rc_yaw = graph_add_node_const(graph, "RC Yaw"); + ps->rc_throttle = graph_add_node_const(graph, "RC Throttle"); + + ps->mixer = graph_add_node_mixer(graph, "Signal Mixer"); + + ps->dt = graph_add_node_const(graph, "dT"); + + // Connect pitch PID chain + 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->theta_dot, CONST_VAL); + graph_set_source(graph, ps->pitch_r_pid, PID_DT, ps->dt, CONST_VAL); + graph_set_source(graph, ps->pitch_pid, PID_SETPOINT, ps->rc_pitch, CONST_VAL); + graph_set_source(graph, ps->pitch_pid, PID_CUR_POINT, ps->cur_pitch, CONST_VAL); + graph_set_source(graph, ps->pitch_pid, PID_DT, ps->dt, 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->phi_dot, CONST_VAL); + graph_set_source(graph, ps->roll_r_pid, PID_DT, ps->dt, CONST_VAL); + graph_set_source(graph, ps->roll_pid, PID_SETPOINT, ps->rc_roll, 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_DT, ps->dt, 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->psi_dot, CONST_VAL); + graph_set_source(graph, ps->yaw_r_pid, PID_DT, ps->dt, CONST_VAL); + /* + graph_set_source(graph, ps->yaw_pid, PID_SETPOINT, ps->rc_yaw, CONST_VAL); + graph_set_source(graph, ps->yaw_pid, PID_CUR_POINT, ps->yaw, CONST_VAL); + graph_set_source(graph, ps->yaw_pid, PID_DT, ps->dt, 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_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); + + // 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_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); + + // 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 angle clamping limits + graph_set_param_val(graph, ps->clamp_pitch, BOUNDS_MIN, -ROLL_PITCH_MAX_ANGLE); + graph_set_param_val(graph, ps->clamp_pitch, BOUNDS_MAX, ROLL_PITCH_MAX_ANGLE); + graph_set_param_val(graph, ps->clamp_roll, BOUNDS_MIN, -ROLL_PITCH_MAX_ANGLE); + graph_set_param_val(graph, ps->clamp_roll, BOUNDS_MAX, ROLL_PITCH_MAX_ANGLE); + + // Set PWM difference clamping limits + graph_set_param_val(graph, ps->clamp_d_pwmP, BOUNDS_MIN, -20000); + graph_set_param_val(graph, ps->clamp_d_pwmP, BOUNDS_MAX, 20000); + graph_set_param_val(graph, ps->clamp_d_pwmR, BOUNDS_MIN, -20000); + graph_set_param_val(graph, ps->clamp_d_pwmR, BOUNDS_MAX, 20000); + graph_set_param_val(graph, ps->clamp_d_pwmY, BOUNDS_MIN, -20000); + graph_set_param_val(graph, ps->clamp_d_pwmY, BOUNDS_MAX, 20000); + + // TODO: Change this to use LOOP_TIME + graph_set_param_val(graph, ps->dt, CONST_SET, 0.005); + + return 0; + } diff --git a/quad/sw/modular_quad_pid/gen_diagram/local_PID.h b/quad/sw/modular_quad_pid/gen_diagram/local_PID.h new file mode 100644 index 0000000000000000000000000000000000000000..376b1f1b921d8aceab6da3120aa58abccdb8a103 --- /dev/null +++ b/quad/sw/modular_quad_pid/gen_diagram/local_PID.h @@ -0,0 +1,85 @@ +/* + * PID.h + * + * Created on: Nov 10, 2014 + * Author: ucart + */ + +#ifndef PID_H_ +#define PID_H_ + +// Yaw constants + +// when using units of degrees +//#define YAW_ANGULAR_VELOCITY_KP 40.0f +//#define YAW_ANGULAR_VELOCITY_KI 0.0f +//#define YAW_ANGULAR_VELOCITY_KD 0.0f +//#define YAW_ANGLE_KP 2.6f +//#define YAW_ANGLE_KI 0.0f +//#define YAW_ANGLE_KD 0.0f + +// when using units of radians +#define YAW_ANGULAR_VELOCITY_KP 190.0f * 2292.0f//200.0f * 2292.0f +#define YAW_ANGULAR_VELOCITY_KI 0.0f +#define YAW_ANGULAR_VELOCITY_KD 0.0f +#define YAW_ANGLE_KP 2.6f +#define YAW_ANGLE_KI 0.0f +#define YAW_ANGLE_KD 0.0f + +// Roll constants +//#define ROLL_ANGULAR_VELOCITY_KP 0.95f +//#define ROLL_ANGULAR_VELOCITY_KI 0.0f +//#define ROLL_ANGULAR_VELOCITY_KD 0.13f//0.4f//0.7f +//#define ROLL_ANGLE_KP 17.0f //9.0f +//#define ROLL_ANGLE_KI 0.0f +//#define ROLL_ANGLE_KD 0.3f // 0.2f +//#define YPOS_KP 0.0f +//#define YPOS_KI 0.0f +//#define YPOS_KD 0.0f + +// when using units of radians +#define ROLL_ANGULAR_VELOCITY_KP 100.0f*46.0f//102.0f*46.0f//9384.0f//204.0f * 46.0f +#define ROLL_ANGULAR_VELOCITY_KI 0.0f +#define ROLL_ANGULAR_VELOCITY_KD 100.f*5.5f//102.0f*6.8f//1387.2//204.0f * 6.8f +#define ROLL_ANGLE_KP 15.0f +#define ROLL_ANGLE_KI 0.0f +#define ROLL_ANGLE_KD 0.2f +#define YPOS_KP 0.015f +#define YPOS_KI 0.005f +#define YPOS_KD 0.03f + + +//Pitch constants + +// when using units of degrees +//#define PITCH_ANGULAR_VELOCITY_KP 0.95f +//#define PITCH_ANGULAR_VELOCITY_KI 0.0f +//#define PITCH_ANGULAR_VELOCITY_KD 0.13f//0.35f//0.7f +//#define PITCH_ANGLE_KP 17.0f // 7.2f +//#define PITCH_ANGLE_KI 0.0f +//#define PITCH_ANGLE_KD 0.3f //0.3f +//#define XPOS_KP 40.0f +//#define XPOS_KI 0.0f +//#define XPOS_KD 10.0f//0.015f + +// when using units of radians +#define PITCH_ANGULAR_VELOCITY_KP 100.0f*46.0f//101.0f*46.0f//9292.0f//202.0f * 46.0f +#define PITCH_ANGULAR_VELOCITY_KI 0.0f +#define PITCH_ANGULAR_VELOCITY_KD 100.0f*5.5f//101.0f*6.8f//1373.6//202.0f * 6.8f +#define PITCH_ANGLE_KP 15.0f +#define PITCH_ANGLE_KI 0.0f +#define PITCH_ANGLE_KD 0.2f +#define XPOS_KP -0.015f +#define XPOS_KI -0.005f +#define XPOS_KD -0.03f + + +//Throttle constants +#define ALT_ZPOS_KP 9804.0f +#define ALT_ZPOS_KI 817.0f +#define ALT_ZPOS_KD 7353.0f + +// Computes control error and correction +PID_values pid_computation(PID_t *pid); + +#endif /* PID_H_ */