Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Path: blob/master/Blimp/Loiter.cpp
Views: 1798
#include "Blimp.h"12#include <AC_AttitudeControl/AC_PosControl.h>34#define MA 0.995#define MO (1-MA)67void Loiter::run(Vector3f& target_pos, float& target_yaw, Vector4b axes_disabled)8{9const float dt = blimp.scheduler.get_last_loop_time_s();1011float scaler_xz_n;12float xz_out = fabsf(blimp.motors->front_out) + fabsf(blimp.motors->down_out);13if (xz_out > 1) {14scaler_xz_n = 1 / xz_out;15} else {16scaler_xz_n = 1;17}18scaler_xz = scaler_xz*MA + scaler_xz_n*MO;1920float scaler_yyaw_n;21float yyaw_out = fabsf(blimp.motors->right_out) + fabsf(blimp.motors->yaw_out);22if (yyaw_out > 1) {23scaler_yyaw_n = 1 / yyaw_out;24} else {25scaler_yyaw_n = 1;26}27scaler_yyaw = scaler_yyaw*MA + scaler_yyaw_n*MO;2829#if HAL_LOGGING_ENABLED30AP::logger().WriteStreaming("BSC", "TimeUS,xz,yyaw,xzn,yyawn",31"Qffff",32AP_HAL::micros64(),33scaler_xz, scaler_yyaw, scaler_xz_n, scaler_yyaw_n);34#endif3536float yaw_ef = blimp.ahrs.get_yaw();37Vector3f err_xyz = target_pos - blimp.pos_ned;38float err_yaw = wrap_PI(target_yaw - yaw_ef);3940Vector4b zero;41if ((fabsf(err_xyz.x) < blimp.g.pid_dz) || !blimp.motors->_armed || (blimp.g.dis_mask & (1<<(2-1)))) {42zero.x = true;43}44if ((fabsf(err_xyz.y) < blimp.g.pid_dz) || !blimp.motors->_armed || (blimp.g.dis_mask & (1<<(1-1)))) {45zero.y = true;46}47if ((fabsf(err_xyz.z) < blimp.g.pid_dz) || !blimp.motors->_armed || (blimp.g.dis_mask & (1<<(3-1)))) {48zero.z = true;49}50if ((fabsf(err_yaw) < blimp.g.pid_dz) || !blimp.motors->_armed || (blimp.g.dis_mask & (1<<(4-1)))) {51zero.yaw = true;52}5354//Disabled means "don't update PIDs or output anything at all". Zero means actually output zero thrust. I term is limited in either case."55Vector4b limit = zero || axes_disabled;5657Vector3f target_vel_ef;58if (!axes_disabled.x && !axes_disabled.y) target_vel_ef = {blimp.pid_pos_xy.update_all(target_pos, blimp.pos_ned, dt, {(float)limit.x, (float)limit.y, (float)limit.z}), 0};59if (!axes_disabled.z) {60target_vel_ef.z = blimp.pid_pos_z.update_all(target_pos.z, blimp.pos_ned.z, dt, limit.z);61}6263float target_vel_yaw = 0;64if (!axes_disabled.yaw) {65target_vel_yaw = blimp.pid_pos_yaw.update_error(wrap_PI(target_yaw - yaw_ef), dt, limit.yaw);66blimp.pid_pos_yaw.set_target_rate(target_yaw);67blimp.pid_pos_yaw.set_actual_rate(yaw_ef);68}6970Vector3f target_vel_ef_c{constrain_float(target_vel_ef.x, -blimp.g.max_vel_xy, blimp.g.max_vel_xy),71constrain_float(target_vel_ef.y, -blimp.g.max_vel_xy, blimp.g.max_vel_xy),72constrain_float(target_vel_ef.z, -blimp.g.max_vel_z, blimp.g.max_vel_z)};73float target_vel_yaw_c = constrain_float(target_vel_yaw, -blimp.g.max_vel_yaw, blimp.g.max_vel_yaw);7475Vector2f target_vel_ef_c_scaled_xy = {target_vel_ef_c.x * scaler_xz, target_vel_ef_c.y * scaler_yyaw};76Vector2f vel_ned_filtd_scaled_xy = {blimp.vel_ned_filtd.x * scaler_xz, blimp.vel_ned_filtd.y * scaler_yyaw};7778Vector2f actuator;79if (!axes_disabled.x && !axes_disabled.y) actuator = blimp.pid_vel_xy.update_all(target_vel_ef_c_scaled_xy, vel_ned_filtd_scaled_xy, dt, {(float)limit.x, (float)limit.y});80float act_down = 0;81if (!axes_disabled.z) {82act_down = blimp.pid_vel_z.update_all(target_vel_ef_c.z * scaler_xz, blimp.vel_ned_filtd.z * scaler_xz, dt, limit.z);83}84blimp.rotate_NE_to_BF(actuator);85float act_yaw = 0;86if (!axes_disabled.yaw) {87act_yaw = blimp.pid_vel_yaw.update_all(target_vel_yaw_c * scaler_yyaw, blimp.vel_yaw_filtd * scaler_yyaw, dt, limit.yaw);88}8990if (!blimp.motors->armed()) {91blimp.pid_pos_xy.set_integrator(Vector2f(0,0));92blimp.pid_pos_z.set_integrator(0);93blimp.pid_pos_yaw.set_integrator(0);94blimp.pid_vel_xy.set_integrator(Vector2f(0,0));95blimp.pid_vel_z.set_integrator(0);96blimp.pid_vel_yaw.set_integrator(0);97target_pos = blimp.pos_ned;98target_yaw = blimp.ahrs.get_yaw();99}100101if (zero.x) {102blimp.motors->front_out = 0;103} else if (axes_disabled.x);104else {105blimp.motors->front_out = actuator.x;106}107if (zero.y) {108blimp.motors->right_out = 0;109} else if (axes_disabled.y);110else {111blimp.motors->right_out = actuator.y;112}113if (zero.z) {114blimp.motors->down_out = 0;115} else if (axes_disabled.z);116else {117blimp.motors->down_out = act_down;118}119if (zero.yaw) {120blimp.motors->yaw_out = 0;121} else if (axes_disabled.yaw);122else {123blimp.motors->yaw_out = act_yaw;124}125126#if HAL_LOGGING_ENABLED127AC_PosControl::Write_PSCN(0.0, target_pos.x * 100.0, blimp.pos_ned.x * 100.0, 0.0, target_vel_ef_c.x * 100.0, blimp.vel_ned_filtd.x * 100.0, 0.0, 0.0, 0.0);128AC_PosControl::Write_PSCE(0.0, target_pos.y * 100.0, blimp.pos_ned.y * 100.0, 0.0, target_vel_ef_c.y * 100.0, blimp.vel_ned_filtd.y * 100.0, 0.0, 0.0, 0.0);129AC_PosControl::Write_PSCD(0.0, -target_pos.z * 100.0, -blimp.pos_ned.z * 100.0, 0.0, -target_vel_ef_c.z * 100.0, -blimp.vel_ned_filtd.z * 100.0, 0.0, 0.0, 0.0);130#endif131}132133void Loiter::run_vel(Vector3f& target_vel_ef, float& target_vel_yaw, Vector4b axes_disabled)134{135const float dt = blimp.scheduler.get_last_loop_time_s();136137Vector4b zero;138if (!blimp.motors->_armed || (blimp.g.dis_mask & (1<<(2-1)))) {139zero.x = true;140}141if (!blimp.motors->_armed || (blimp.g.dis_mask & (1<<(1-1)))) {142zero.y = true;143}144if (!blimp.motors->_armed || (blimp.g.dis_mask & (1<<(3-1)))) {145zero.z = true;146}147if (!blimp.motors->_armed || (blimp.g.dis_mask & (1<<(4-1)))) {148zero.yaw = true;149}150//Disabled means "don't update PIDs or output anything at all". Zero means actually output zero thrust. I term is limited in either case."151Vector4b limit = zero || axes_disabled;152153Vector3f target_vel_ef_c{constrain_float(target_vel_ef.x, -blimp.g.max_vel_xy, blimp.g.max_vel_xy),154constrain_float(target_vel_ef.y, -blimp.g.max_vel_xy, blimp.g.max_vel_xy),155constrain_float(target_vel_ef.z, -blimp.g.max_vel_z, blimp.g.max_vel_z)};156float target_vel_yaw_c = constrain_float(target_vel_yaw, -blimp.g.max_vel_yaw, blimp.g.max_vel_yaw);157158Vector2f target_vel_ef_c_scaled_xy = {target_vel_ef_c.x * scaler_xz, target_vel_ef_c.y * scaler_yyaw};159Vector2f vel_ned_filtd_scaled_xy = {blimp.vel_ned_filtd.x * scaler_xz, blimp.vel_ned_filtd.y * scaler_yyaw};160161Vector2f actuator;162if (!axes_disabled.x && !axes_disabled.y) actuator = blimp.pid_vel_xy.update_all(target_vel_ef_c_scaled_xy, vel_ned_filtd_scaled_xy, dt, {(float)limit.x, (float)limit.y});163float act_down = 0;164if (!axes_disabled.z) {165act_down = blimp.pid_vel_z.update_all(target_vel_ef_c.z * scaler_xz, blimp.vel_ned_filtd.z * scaler_xz, dt, limit.z);166}167blimp.rotate_NE_to_BF(actuator);168float act_yaw = 0;169if (!axes_disabled.yaw) {170act_yaw = blimp.pid_vel_yaw.update_all(target_vel_yaw_c * scaler_yyaw, blimp.vel_yaw_filtd * scaler_yyaw, dt, limit.yaw);171}172173if (!blimp.motors->armed()) {174blimp.pid_vel_xy.set_integrator(Vector2f(0,0));175blimp.pid_vel_z.set_integrator(0);176blimp.pid_vel_yaw.set_integrator(0);177}178179if (zero.x) {180blimp.motors->front_out = 0;181} else if (axes_disabled.x);182else {183blimp.motors->front_out = actuator.x;184}185if (zero.y) {186blimp.motors->right_out = 0;187} else if (axes_disabled.y);188else {189blimp.motors->right_out = actuator.y;190}191if (zero.z) {192blimp.motors->down_out = 0;193} else if (axes_disabled.z);194else {195blimp.motors->down_out = act_down;196}197if (zero.yaw) {198blimp.motors->yaw_out = 0;199} else if (axes_disabled.yaw);200else {201blimp.motors->yaw_out = act_yaw;202}203204#if HAL_LOGGING_ENABLED205AC_PosControl::Write_PSCN(0.0, 0.0, blimp.pos_ned.x * 100.0, 0.0, target_vel_ef_c.x * 100.0, blimp.vel_ned_filtd.x * 100.0, 0.0, 0.0, 0.0);206AC_PosControl::Write_PSCE(0.0, 0.0, blimp.pos_ned.y * 100.0, 0.0, target_vel_ef_c.y * 100.0, blimp.vel_ned_filtd.y * 100.0, 0.0, 0.0, 0.0);207AC_PosControl::Write_PSCD(0.0, 0.0, -blimp.pos_ned.z * 100.0, 0.0, -target_vel_ef_c.z * 100.0, -blimp.vel_ned_filtd.z * 100.0, 0.0, 0.0, 0.0);208#endif209}210211212