ACfly的Ctrl_Attitude.cpp的代码
ACfly的Ctrl_Attitude.cpp的代码
Attitude是姿势的意思
#include "ctrl_Attitude.hpp"
#include "ControlSystem.hpp"
#include "ctrl_Main.hpp"
#include "Parameters.hpp"
#include "MeasurementSystem.hpp"
#include "TD4.hpp"
#include "TD3_3D.hpp"
#include "ESO_AngularRate.hpp"
#include "ESO_h.hpp"
#include "Filters_LP.hpp"
#include "drv_PWMOut.hpp"
#include "Receiver.hpp"#include "StorageSystem.hpp"/*参数*///飞行器类型enum UAVType{UAVType_Rotor4_X = 10 , //四旋翼X型UAVType_Rotor6_X = 11 , //六旋翼X型UAVType_Rotor8_X = 12 , //八旋翼X型UAVType_Rotor4_C = 15 , //四旋翼十字型UAVType_Rotor42_C = 20 , //四旋翼Double十字型UAVType_Rotor6_S1 = 32 , //六旋翼异构};//控制参数struct AttCtrlCfg{uint64_t UAVType; //机型类型float STThrottle[2]; //起转油门float NonlinearFactor[2]; //电机非线性参数float FullThrRatio[2]; //满油门比例float T[2]; //惯性时间Tfloat b[6]; //RPY增益bfloat TD4_P1[6]; //RPY前馈TD4滤波器P1float TD4_P2[6]; //RPY前馈TD4滤波器P2float TD4_P3[6]; //RPY前馈TD4滤波器P3float TD4_P4[6]; //RPY前馈TD4滤波器P4float P1[6]; //反馈增益P1float P2[6]; //反馈增益P2float P3[6]; //反馈增益P3float P4[6]; //反馈增益P4float beta2[2]; //ESO Beta2float maxLean[2]; //最大倾斜角float maxRPSp[2]; //最大Pitch Roll速度float maxRPAcc[2]; //最大Pitch Roll加速度float maxYSp[2]; //最大偏航速度float maxYAcc[2]; //最大偏航加速度}__PACKED;//参数static AttCtrlCfg cfg;
/*参数*//*内部接口*/float get_STThrottle(){return cfg.STThrottle[0];}float get_maxLean(){return cfg.maxLean[0];}float get_maxYawSpeed(){return cfg.maxYSp[0];}
/*内部接口*//*起飞地点*/static bool HomeLatLonAvailable;static bool HomeAvailable;static vector2<double> HomeLatLon;static vector2<double> HomePoint;static double HomeLocalZ = 0;bool getHomeLocalZ( double* home, double TIMEOUT ){if( LockCtrl(TIMEOUT) ){*home = HomeLocalZ;UnlockCtrl();return true;}return false;}bool getHomePoint( vector2<double>* home, double TIMEOUT ){if( LockCtrl(TIMEOUT) ){bool available = HomeAvailable;if(available)*home = HomePoint;UnlockCtrl();if( available )return true;elsereturn false;}return false;}bool getHomeLatLon( vector2<double>* home, double TIMEOUT ){if( LockCtrl(TIMEOUT) ){bool available = HomeLatLonAvailable;if(available)*home = HomeLatLon;UnlockCtrl();if( available )return true;elsereturn false;}return false;}
/*起飞地点*//*状态观测器*///姿态ESOstatic ESO_AngularRate ESO[3];//高度ESOstatic double throttle_u = 0;static ESO_h ESO_height;static double hover_throttle = 0;static double WindDisturbance_x = 0;static double WindDisturbance_y = 0;static bool inFlight = false;static inline void update_output_throttle( double throttle, double h ){Quaternion quat;get_Airframe_quat( &quat, 0.1 );double output_minimum_throttle = cfg.STThrottle[0];double lean_cosin = quat.get_lean_angle_cosin();//观测悬停油门double r_throttle = throttle - output_minimum_throttle;if( r_throttle < 0 )r_throttle = 0;if( lean_cosin < 0.1f )lean_cosin = 0.1f;r_throttle *= lean_cosin; throttle_u = r_throttle;ESO_height.update_u(r_throttle);hover_throttle = ESO_height.get_hover_throttle() + output_minimum_throttle;//更新飞行状态static uint16_t onGround_counter = 0;if( inFlight == false ){onGround_counter = 0;double AccZ = ESO_height.get_force() - GravityAcc;if( AccZ > 20 && throttle > output_minimum_throttle + 5 )inFlight = true;}else{vector3<double> angular_rate;get_EsAngularRate(&angular_rate);double rate = safe_sqrt(angular_rate.get_square());if( hover_throttle<output_minimum_throttle+2 && rad2degree(rate)<10 ){if( ++onGround_counter >= 400 )inFlight = false;}elseonGround_counter = 0;}//观测水平分力if( inFlight ){vector3<double> AccENU;get_AccelerationENU_Ctrl(&AccENU);Quaternion quat;get_AirframeY_quat( &quat );vector3<double> active_force_xy_vec = quat.rotate_axis_z();if( lean_cosin < 0.3f )lean_cosin = 0.3f;active_force_xy_vec = active_force_xy_vec *( ( AccENU.z + GravityAcc ) / lean_cosin );vector3<double> WindDisturbance_xy;WindDisturbance_xy.x = AccENU.x - active_force_xy_vec.x;WindDisturbance_xy.y = AccENU.y - active_force_xy_vec.y;double lp_factor = 2 * Pi * (1.0/CtrlRateHz) * 1.2;WindDisturbance_x += lp_factor * ( WindDisturbance_xy.x - WindDisturbance_x );WindDisturbance_y += lp_factor * ( WindDisturbance_xy.y - WindDisturbance_y );}elseWindDisturbance_x = WindDisturbance_y = 0;//更新Home点位置if( inFlight == false ){vector3<double> position;get_Position(&position);HomeLocalZ = position.z;PosSensorHealthInf2 posInf;if( get_Health_XY(&posInf) ){HomeAvailable = true;HomePoint.x = posInf.PositionENU.x;HomePoint.y = posInf.PositionENU.y;}elseHomeAvailable = false;if( get_OptimalGlobal_XY(&posInf) ){HomeLatLonAvailable = true;map_projection_reproject( &posInf.mp, posInf.PositionENU.x+posInf.HOffset.x, posInf.PositionENU.y+posInf.HOffset.y,&HomeLatLon.x, &HomeLatLon.y );} }else if( get_Position_MSStatus()!= MS_Ready )HomeAvailable = false;}static double Roll_u = 0;static double Pitch_u = 0;static double Yaw_u = 0;void update_ESO_1(){//更新角速度观测器vector3<double> angular_rate;get_AngularRate_Ctrl(&angular_rate);ESO[0].run(angular_rate.x);ESO[1].run(angular_rate.y);ESO[2].run(angular_rate.z);vector3<double> acc;get_AccelerationENU_Ctrl(&acc);ESO_height.run( acc.z );} void update_ESO_2(){ESO[0].update_u(Roll_u);ESO[1].update_u(Pitch_u);ESO[2].update_u(Yaw_u);ESO_height.update_u(throttle_u);}
/*状态观测器*/ /*观测器接口*/bool get_hover_throttle( double* result, double TIMEOUT ){if( LockCtrl(TIMEOUT) ){*result = hover_throttle;UnlockCtrl();return true;}return false;}bool get_throttle_force( double* result, double TIMEOUT ){if( LockCtrl(TIMEOUT) ){*result = ESO_height.get_force();UnlockCtrl();return true;}return false;}bool get_throttle_b( double* result, double TIMEOUT ){if( LockCtrl(TIMEOUT) ){*result = ESO_height.get_b();UnlockCtrl();return true;}return false;}bool get_ESO_height_T( double* result, double TIMEOUT ){if( LockCtrl(TIMEOUT) ){*result = ESO_height.get_T();UnlockCtrl();return true;}return false;}bool get_is_inFlight( bool* result, double TIMEOUT ){*result = inFlight;return true;}bool get_WindDisturbance( vector3<double>* result, double TIMEOUT ){if( LockCtrl(TIMEOUT) ){*result = vector3<double>( WindDisturbance_x, WindDisturbance_y, 0 );;UnlockCtrl();return true;}return false; }bool get_EsAngularRate( vector3<double>* result, double TIMEOUT ){if( LockCtrl(TIMEOUT) ){*result = vector3<double>( ESO[0].get_EsAngularRate(), ESO[1].get_EsAngularRate(), ESO[2].get_EsAngularRate() );UnlockCtrl();return true;}return false; }bool get_EsAngularAcc( vector3<double>* result, double TIMEOUT ){if( LockCtrl(TIMEOUT) ){*result = vector3<double>( ESO[0].get_EsAngularAcceleration(), ESO[1].get_EsAngularAcceleration(), ESO[2].get_EsAngularAcceleration() );UnlockCtrl();return true;}return false; }
/*观测器接口*//*控制接口*///期望TD4滤波器static TD3_2DSL Target_tracker_RP;static TD4_SL Target_trackerY;//姿态控制模式static bool Attitude_Control_Enabled = false;static Attitude_ControlMode RollPitch_ControlMode = Attitude_ControlMode_Angle;static Attitude_ControlMode Yaw_ControlMode = Attitude_ControlMode_Angle;//输出滤波器static double outRoll_filted = 0;static double outPitch_filted = 0;static double outYaw_filted = 0;static double throttle = 0;static double target_Roll;static double target_Pitch;static double target_Yaw;static vector3<double> target_AngularRate;bool is_Attitude_Control_Enabled( bool* enabled, double TIMEOUT ){*enabled = Attitude_Control_Enabled;return true;}bool Attitude_Control_Enable( double TIMEOUT ){if( get_Attitude_MSStatus() != MS_Ready )return false;Quaternion quat;if( get_Airframe_quat( &quat, TIMEOUT ) == false )return false;if( LockCtrl(TIMEOUT) ){if( Attitude_Control_Enabled == true ){ //控制器已打开UnlockCtrl();return false;}//读参数if( ReadParamGroup( "AttCtrl", (uint64_t*)&cfg, 0, TIMEOUT ) != PR_OK ){UnlockCtrl();return false;}/*初始化*/ //读取电池电压float BatVoltage = get_MainBatteryVoltage_filted();//计算增益修正系数double b_scale = 1.0;if( BatVoltage > 7 ){float STVoltage[2];if( ReadParam("Bat_STVoltage", 0, 0, (uint64_t*)STVoltage, 0 ) == PR_OK )b_scale = BatVoltage / STVoltage[0];}//初始化姿态ESOESO[0].init( cfg.T[0], cfg.b[0]*b_scale, 25, cfg.beta2[0], CtrlRateHz*CtrlRateDiv );ESO[1].init( cfg.T[0], cfg.b[2]*b_scale, 25, cfg.beta2[0], CtrlRateHz*CtrlRateDiv );ESO[2].init( 1.0/(CtrlRateHz*CtrlRateDiv), cfg.b[4]*b_scale, 25, cfg.beta2[0], CtrlRateHz*CtrlRateDiv );//初始化高度ESOESO_height.init( cfg.T[0], 10, CtrlRateHz*CtrlRateDiv );//初始化期望TD4滤波器Target_tracker_RP.P1=cfg.TD4_P1[0];Target_tracker_RP.P2=cfg.TD4_P2[0];Target_tracker_RP.P3=cfg.TD4_P3[0];Target_tracker_RP.r2=degree2rad(cfg.maxRPSp[0]);Target_tracker_RP.r3=degree2rad(cfg.maxRPAcc[0]);Target_tracker_RP.r4=degree2rad(100000.0); Target_trackerY.P1=cfg.TD4_P1[4];Target_trackerY.P2=cfg.TD4_P2[4];Target_trackerY.P3=cfg.TD4_P3[4];Target_trackerY.P4=cfg.TD4_P4[4];Target_trackerY.r2n=Target_trackerY.r2p=degree2rad(cfg.maxYSp[0]);Target_trackerY.r3n=Target_trackerY.r3p=degree2rad(cfg.maxYAcc[0]);/*初始化*/double pwm_out[8] = { -200, -200, -200, -200, -200, -200, -200, -200 };switch( cfg.UAVType ){case UAVType_Rotor4_X:{for( uint8_t i = 0; i < 4; ++i ){pwm_out[i] = cfg.STThrottle[0];PWM_Out( pwm_out );os_delay(0.3);}break;}case UAVType_Rotor6_X:{for( uint8_t i = 0; i < 6; ++i ){pwm_out[i] = cfg.STThrottle[0];PWM_Out( pwm_out );os_delay(0.3);}break;}case UAVType_Rotor8_X:{for( uint8_t i = 0; i < 8; ++i ){pwm_out[i] = cfg.STThrottle[0];PWM_Out( pwm_out );os_delay(0.3);}break;}case UAVType_Rotor6_S1:{for( uint8_t i = 0; i < 6; ++i ){pwm_out[i] = cfg.STThrottle[0];PWM_Out( pwm_out );os_delay(0.3);}break;}default:{UnlockCtrl();return false;}}Attitude_Control_Enabled = true;target_Yaw = quat.getYaw();target_Roll = target_Pitch = 0;RollPitch_ControlMode = Attitude_ControlMode_Angle;Yaw_ControlMode = Attitude_ControlMode_Angle;//更新控制时间bool isMSafe = (xTaskGetCurrentTaskHandle()==MSafeTaskHandle);if(!isMSafe)last_ZCtrlTime = last_XYCtrlTime = TIME::now();UnlockCtrl();return true;}return false;}bool Attitude_Control_Disable( double TIMEOUT ){if( LockCtrl(TIMEOUT) ){if( Attitude_Control_Enabled == false ){UnlockCtrl();return false;}Altitude_Control_Disable();Position_Control_Disable();Attitude_Control_Enabled = false; UnlockCtrl();return true;}return false;}bool get_Target_Throttle( double* result, double TIMEOUT ){if( LockCtrl(TIMEOUT) ){*result = throttle;UnlockCtrl();return true;}return false;}bool Attitude_Control_set_Throttle( double thr, double TIMEOUT ){if( isnan(thr) || isinf(thr) )return false;if( LockCtrl(TIMEOUT) ){if( Attitude_Control_Enabled == false ){UnlockCtrl();return false;}bool alt_enabled;is_Altitude_Control_Enabled(&alt_enabled);bool isMSafe = (xTaskGetCurrentTaskHandle()==MSafeTaskHandle);if( !isMSafe && alt_enabled==false && ForceMSafeCtrl ){ //屏蔽用户控制last_ZCtrlTime = TIME::now();UnlockCtrl();return false;}throttle = thr;//更新控制时间 if(!isMSafe && alt_enabled==false)last_ZCtrlTime = TIME::now();UnlockCtrl();return true;}return false;}bool Attitude_Control_get_Target_RollPitch( double* Roll, double* Pitch, double TIMEOUT ){if( LockCtrl(TIMEOUT) ){if( Attitude_Control_Enabled == false ){UnlockCtrl();return false;}*Roll = target_Roll;*Pitch = target_Pitch;UnlockCtrl();return true;}return false;}bool Attitude_Control_set_Target_RollPitch( double Roll, double Pitch, double TIMEOUT ){if( isnan(Roll) || isinf(Roll) || isnan(Pitch) || isinf(Pitch) )return false;if( LockCtrl(TIMEOUT) ){if( Attitude_Control_Enabled == false ){UnlockCtrl();return false;}bool pos_enabled;is_Position_Control_Enabled(&pos_enabled);bool isMSafe = (xTaskGetCurrentTaskHandle()==MSafeTaskHandle);if( !isMSafe && pos_enabled==false && ForceMSafeCtrl ){ //屏蔽用户控制last_ZCtrlTime = TIME::now();UnlockCtrl();return false;}double angle = safe_sqrt( Roll*Roll + Pitch*Pitch );if( angle > degree2rad(cfg.maxLean[0]) ){double scale = degree2rad(cfg.maxLean[0]) / angle;Roll *= scale;Pitch *= scale;} target_Roll = Roll;target_Pitch = Pitch;RollPitch_ControlMode = Attitude_ControlMode_Angle;//更新控制时间if(!isMSafe && pos_enabled==false)last_XYCtrlTime = TIME::now();UnlockCtrl();return true;}return false;}bool Attitude_Control_set_Target_Yaw( double Yaw, double TIMEOUT ){ if( isnan(Yaw) || isinf(Yaw) )return false;//屏蔽用户控制bool isMSafe = (xTaskGetCurrentTaskHandle()==MSafeTaskHandle);if( !isMSafe && ForceMSafeCtrl )return false;Quaternion quat, quatY;get_Airframe_quat(&quat);get_AirframeY_quat(&quatY);if( LockCtrl(TIMEOUT) ){if( Attitude_Control_Enabled == false ){UnlockCtrl();return false;}if( Yaw_ControlMode != Attitude_ControlMode_Angle ){Target_trackerY.x1 = quat.getYaw();Yaw_ControlMode = Attitude_ControlMode_Angle;}double yaw_err = Mod( Yaw - quatY.getYaw(), 2*Pi );if(yaw_err > Pi)yaw_err -= 2*Pi;while(yaw_err < -Pi)yaw_err += 2*Pi;target_Yaw = Target_trackerY.x1 + yaw_err;UnlockCtrl();return true;}return false;}bool Attitude_Control_set_Target_YawRelative( double Yaw, double TIMEOUT ){ if( isnan(Yaw) || isinf(Yaw) )return false;//屏蔽用户控制bool isMSafe = (xTaskGetCurrentTaskHandle()==MSafeTaskHandle);if( !isMSafe && ForceMSafeCtrl )return false;Quaternion quat;get_Airframe_quat(&quat);if( LockCtrl(TIMEOUT) ){if( Attitude_Control_Enabled == false ){UnlockCtrl();return false;}double currentYaw = quat.getYaw();if( Yaw_ControlMode != Attitude_ControlMode_Angle ){Target_trackerY.x1 = currentYaw;Yaw_ControlMode = Attitude_ControlMode_Angle;}target_Yaw = Target_trackerY.x1 + Yaw;UnlockCtrl();return true;}return false;}bool Attitude_Control_set_Target_YawRate( double YawRate, double TIMEOUT ){if( isnan(YawRate) || isinf(YawRate) )return false;//屏蔽用户控制bool isMSafe = (xTaskGetCurrentTaskHandle()==MSafeTaskHandle);if( !isMSafe && ForceMSafeCtrl )return false;if( LockCtrl(TIMEOUT) ){if( Attitude_Control_Enabled == false ){UnlockCtrl();return false;}target_AngularRate.z = YawRate;Yaw_ControlMode = Attitude_ControlMode_AngularRate;UnlockCtrl();return true;}return false;}bool Attitude_Control_set_YawLock( double TIMEOUT ){//屏蔽用户控制bool isMSafe = (xTaskGetCurrentTaskHandle()==MSafeTaskHandle);if( !isMSafe && ForceMSafeCtrl )return false;if( LockCtrl(TIMEOUT) ){if( Attitude_Control_Enabled == false ){UnlockCtrl();return false;}if( Yaw_ControlMode == Attitude_ControlMode_AngularRate )Yaw_ControlMode = Attitude_ControlMode_Locking;UnlockCtrl();return true;}return false;}
/*控制接口*///四旋翼X模式
static void ctrl_Attitude_MultiRotor_X4_PWM( double outRoll , double outPitch , double outYaw );
//六旋翼X模式
static void ctrl_Attitude_MultiRotor_X6_PWM( double outRoll , double outPitch , double outYaw );
//六旋翼异构
/*o--oo--oo--o
*/
static void ctrl_Attitude_MultiRotor_S6_1_PWM( double outRoll , double outPitch , double outYaw );
//八旋翼X模式
static void ctrl_Attitude_MultiRotor_X8_PWM( double outRoll , double outPitch , double outYaw );void ctrl_Attitude()
{ double h = 1.0 / CtrlRateHz;if( Attitude_Control_Enabled == false ){Roll_u = Pitch_u = Yaw_u = 0;update_output_throttle( 0 , h );PWM_PullDownAll();return;} //Debug保护//油门低于起转油门拉低所有输出Receiver rc;getReceiver(&rc);if( throttle < cfg.STThrottle[0] - 0.1 || ( (rc.available && rc.data[0] < cfg.STThrottle[0] - 0.1) && (rc.data[1] < 10) ) ){Roll_u = Pitch_u = Yaw_u = 0;update_output_throttle( 0 , h );PWM_PullDownAll();return;}// //根据电池电压调整控制对象增益
// float BatV = getBatteryVoltage();
// float VST = Cfg_get_BatSTVoltage();
// if( BatV > 7 && VST > 7 )
// {
// float scale = BatV / VST;
// ESO[0].b = Cfg_get_RPYCtrl_b(0) * scale;
// ESO[1].b = Cfg_get_RPYCtrl_b(1) * scale;
// ESO[2].b = Cfg_get_RPYCtrl_b(2) * scale;
// }
// else
// {
// ESO[0].b = Cfg_get_RPYCtrl_b(0);
// ESO[1].b = Cfg_get_RPYCtrl_b(1);
// ESO[2].b = Cfg_get_RPYCtrl_b(2);
// }//读取电池电压float BatVoltage = get_MainBatteryVoltage_filted();//计算增益修正系数double b_scale = 1.0;if( BatVoltage > 7 ){float STVoltage[2];if( ReadParam("Bat_STVoltage", 0, 0, (uint64_t*)STVoltage, 0 ) == PR_OK )b_scale = BatVoltage / STVoltage[0];}//根据电池电压调整控制对象增益ESO[0].b = cfg.b[0] * b_scale;ESO[1].b = cfg.b[2] * b_scale;ESO[2].b = cfg.b[4] * b_scale;Quaternion AirframeQuat;get_Airframe_quat( &AirframeQuat, 0.1 );//获取控制参数double Ps = cfg.P1[0];double PsY = cfg.P1[4];vector3<double> P2( cfg.P2[0], cfg.P2[2], cfg.P2[4] );vector3<double> P3( cfg.P3[0], cfg.P3[2], cfg.P3[4] );//目标Roll Pitch四元数Quaternion target_quat_PR; //目标角速度vector3<double> target_angular_velocity;//获取当前四元数的Pitch Roll分量四元数double Yaw = AirframeQuat.getYaw();double half_sinYaw, half_cosYaw;fast_sin_cos( 0.5*Yaw, &half_sinYaw, &half_cosYaw );Quaternion YawQuat(half_cosYaw ,0 ,0 ,half_sinYaw);YawQuat.conjugate();Quaternion_Ef current_quat_PR = Quaternion_Ef( YawQuat*AirframeQuat );//计算旋转矩阵current_quat_PR.conjugate(); double Rotation_Matrix[3][3]; //反向旋转current_quat_PR.get_rotation_matrix(Rotation_Matrix);current_quat_PR.conjugate(); double Rotation_Matrix_P[3][3]; //正向旋转current_quat_PR.get_rotation_matrix(Rotation_Matrix_P);//运行扩张状态观测器得到估计角速度、角加速度vector3<double> AngularRateCtrl;get_AngularRate_Ctrl( &AngularRateCtrl, 0.1 );vector3<double> angular_rate_ESO;vector3<double> angular_acceleration_ESO;//使用ESO估计角速度、角加速度angular_rate_ESO.set_vector(ESO[0].get_EsAngularRate() ,ESO[1].get_EsAngularRate() ,ESO[2].get_EsAngularRate()); angular_acceleration_ESO.set_vector(ESO[0].get_EsAngularAcceleration() ,ESO[1].get_EsAngularAcceleration() ,ESO[2].get_EsAngularAcceleration());//计算ENU坐标系下的角速度、角加速度vector3<double> angular_rate_ENU;angular_rate_ENU.x = Rotation_Matrix_P[0][0]*angular_rate_ESO.x + Rotation_Matrix_P[0][1]*angular_rate_ESO.y + Rotation_Matrix_P[0][2]*angular_rate_ESO.z;angular_rate_ENU.y = Rotation_Matrix_P[1][0]*angular_rate_ESO.x + Rotation_Matrix_P[1][1]*angular_rate_ESO.y + Rotation_Matrix_P[1][2]*angular_rate_ESO.z;angular_rate_ENU.z = Rotation_Matrix_P[2][0]*angular_rate_ESO.x + Rotation_Matrix_P[2][1]*angular_rate_ESO.y + Rotation_Matrix_P[2][2]*angular_rate_ESO.z;vector3<double> angular_acceleration_ENU;angular_acceleration_ENU.x = Rotation_Matrix_P[0][0]*angular_acceleration_ESO.x + Rotation_Matrix_P[0][1]*angular_acceleration_ESO.y + Rotation_Matrix_P[0][2]*angular_acceleration_ESO.z;angular_acceleration_ENU.y = Rotation_Matrix_P[1][0]*angular_acceleration_ESO.x + Rotation_Matrix_P[1][1]*angular_acceleration_ESO.y + Rotation_Matrix_P[1][2]*angular_acceleration_ESO.z;angular_acceleration_ENU.z = Rotation_Matrix_P[2][0]*angular_acceleration_ESO.x + Rotation_Matrix_P[2][1]*angular_acceleration_ESO.y + Rotation_Matrix_P[2][2]*angular_acceleration_ESO.z;//由Roll Pitch控制模式//计算Roll Pitch目标角速度(ENU系)vector3<double> target_angular_rate_RP;switch( RollPitch_ControlMode ){default:case Attitude_ControlMode_Angle:{//TD4滤目标角度Target_tracker_RP.track3( vector2<double>(target_Roll,target_Pitch), 1.0 / CtrlRateHz );//使用目标角度构造目标四元数//calculate target quat Q1// front// x// ^// |// y < --Odouble half_sinR, half_cosR;fast_sin_cos( 0.5*Target_tracker_RP.x1.x, &half_sinR, &half_cosR );double half_sinP, half_cosP;fast_sin_cos( 0.5*Target_tracker_RP.x1.y, &half_sinP, &half_cosP );target_quat_PR = Quaternion( half_cosR*half_cosP ,half_cosP*half_sinR ,half_cosR*half_sinP ,-half_sinR*half_sinP);//计算误差四元数Q//Q*Q1=Qt Q1为当前机体四元数,Qt为目标四元数//Q=Qt*inv(Q1)Quaternion current_quat_conj = current_quat_PR; current_quat_conj.conjugate();vector3<double> PR_rotation = ( target_quat_PR * current_quat_conj ).get_Rotation_vec();vector3<double> feed_foward_ratePR = { Target_tracker_RP.x2.x, Target_tracker_RP.x2.y , 0 };target_angular_rate_RP = ( PR_rotation * Ps ) + feed_foward_ratePR;break;}}double target_angular_rate_Y;switch(Yaw_ControlMode){case Attitude_ControlMode_Angle:{if(inFlight){//TD4滤目标角度Target_trackerY.r2n = Target_trackerY.r2p = degree2rad(60.0);Target_trackerY.track4( target_Yaw , 1.0f / CtrlRateHz );//角度误差化为-180 - +180double angle_error = Target_trackerY.x1 - Yaw;while( angle_error < -Pi )angle_error+=2*Pi;while( angle_error > Pi )angle_error-=2*Pi;//求目标角速度target_angular_rate_Y = angle_error * Ps + Target_trackerY.x2;target_angular_rate_Y = constrain( target_angular_rate_Y , 2.5 );}else{ Target_trackerY.reset();Target_trackerY.x1 = target_Yaw = Yaw;target_angular_rate_Y = 0;}break;}case Attitude_ControlMode_AngularRate:{if(inFlight){Target_trackerY.r2n=Target_trackerY.r2p=degree2rad(cfg.maxYSp[0]);Target_trackerY.track3( target_AngularRate.z , 1.0 / CtrlRateHz );target_angular_rate_Y = Target_trackerY.x2;}else{ Target_trackerY.reset();Target_trackerY.x1 = target_Yaw = Yaw;target_angular_rate_Y = 0;}break;}case Attitude_ControlMode_Locking:{if(inFlight){Target_trackerY.track3( 0 , 1.0 / CtrlRateHz );target_angular_rate_Y = Target_trackerY.x2;if( in_symmetry_range( target_angular_rate_Y , 0.001 ) && in_symmetry_range( angular_rate_ENU.z , 0.05 ) ){ Target_trackerY.x1 = target_Yaw = Yaw;Yaw_ControlMode = Attitude_ControlMode_Angle;}}else{ Target_trackerY.reset();Target_trackerY.x1 = target_Yaw = Yaw;target_angular_rate_Y = 0;}break;}}//计算前馈量double YawAngleP = ( Target_trackerY.get_tracking_mode() == 4 ) ? ( Ps ) : 0;vector3<double> Tv1_ENU = { Ps*( Target_tracker_RP.x2.x - angular_rate_ENU.x ) + Target_tracker_RP.x3.x ,Ps*( Target_tracker_RP.x2.y - angular_rate_ENU.y ) + Target_tracker_RP.x3.y ,YawAngleP*( Target_trackerY.x2 - angular_rate_ENU.z ) + Target_trackerY.x3 };vector3<double> Tv2_ENU = { Ps*( Target_tracker_RP.x3.x - angular_acceleration_ENU.x ) + Target_tracker_RP.T4.x ,Ps*( Target_tracker_RP.x3.y - angular_acceleration_ENU.y ) + Target_tracker_RP.T4.y,YawAngleP*( Target_trackerY.x3 - angular_acceleration_ENU.z ) + Target_trackerY.x4 };vector3<double> Tv1;Tv1.x = Rotation_Matrix[0][0]*Tv1_ENU.x + Rotation_Matrix[0][1]*Tv1_ENU.y + Rotation_Matrix[0][2]*Tv1_ENU.z;Tv1.y = Rotation_Matrix[1][0]*Tv1_ENU.x + Rotation_Matrix[1][1]*Tv1_ENU.y + Rotation_Matrix[1][2]*Tv1_ENU.z;Tv1.z = Rotation_Matrix[2][0]*Tv1_ENU.x + Rotation_Matrix[2][1]*Tv1_ENU.y + Rotation_Matrix[2][2]*Tv1_ENU.z;vector3<double> Tv2;Tv2.x = Rotation_Matrix[0][0]*Tv2_ENU.x + Rotation_Matrix[0][1]*Tv2_ENU.y + Rotation_Matrix[0][2]*Tv2_ENU.z;Tv2.y = Rotation_Matrix[1][0]*Tv2_ENU.x + Rotation_Matrix[1][1]*Tv2_ENU.y + Rotation_Matrix[1][2]*Tv2_ENU.z;Tv2.z = Rotation_Matrix[2][0]*Tv2_ENU.x + Rotation_Matrix[2][1]*Tv2_ENU.y + Rotation_Matrix[2][2]*Tv2_ENU.z;vector3<double> Ta1 = { P2.x*( Tv1.x - angular_acceleration_ESO.x ) + Tv2.x ,P2.y*( Tv1.y - angular_acceleration_ESO.y ) + Tv2.y ,P2.z*( Tv1.z - angular_acceleration_ESO.z ) + Tv2.z };//计算前馈量//把目标速度从Bodyheading旋转到机体vector3<double> target_angular_rate_ENU;target_angular_rate_ENU.x = target_angular_rate_RP.x;target_angular_rate_ENU.y = target_angular_rate_RP.y;target_angular_rate_ENU.z = target_angular_rate_RP.z + target_angular_rate_Y;vector3<double> target_angular_rate_body;target_angular_rate_body.x = Rotation_Matrix[0][0]*target_angular_rate_ENU.x + Rotation_Matrix[0][1]*target_angular_rate_ENU.y + Rotation_Matrix[0][2]*target_angular_rate_ENU.z;target_angular_rate_body.y = Rotation_Matrix[1][0]*target_angular_rate_ENU.x + Rotation_Matrix[1][1]*target_angular_rate_ENU.y + Rotation_Matrix[1][2]*target_angular_rate_ENU.z;target_angular_rate_body.z = Rotation_Matrix[2][0]*target_angular_rate_ENU.x + Rotation_Matrix[2][1]*target_angular_rate_ENU.y + Rotation_Matrix[2][2]*target_angular_rate_ENU.z;//把目标速度从Bodyheading旋转到机体//计算目标角加速度vector3<double> target_angular_acceleration = target_angular_rate_body - angular_rate_ESO;target_angular_acceleration.x *= P2.x;target_angular_acceleration.y *= P2.y;target_angular_acceleration.z *= P2.z;target_angular_acceleration = target_angular_acceleration + Tv1;//计算目标角加速度//计算角加速度误差vector3<double> angular_acceleration_error = target_angular_acceleration - angular_acceleration_ESO;vector3<double> disturbance(ESO[0].get_EsDisturbance() ,ESO[1].get_EsDisturbance() ,ESO[2].get_EsDisturbance());static vector3<double> last_disturbance = { 0 , 0 , 0 }; vector3<double> disturbance_Derivative = (disturbance - last_disturbance) * CtrlRateHz;last_disturbance = disturbance;double outRoll;double outPitch;double outYaw;if( inFlight ){outRoll = ( ESO[0].get_EsMainPower() + ESO[0].T * ( angular_acceleration_error.x * P3.x + Ta1.x /*- disturbance_x*/ ) )/ESO[0].b;outPitch = ( ESO[1].get_EsMainPower() + ESO[1].T * ( angular_acceleration_error.y * P3.y + Ta1.y /*- disturbance_y*/ ) )/ESO[1].b;
// outYaw = ( ESO_AngularRate_get_EsMainPower( &ESO[2] ) + ESO[2].T * ( angular_acceleration_error.z * P.z + Ta1.z /*- disturbance_z*/ ) )/ESO[2].b;outYaw = ( target_angular_acceleration.z - disturbance.z ) / ESO[2].b;}else{outRoll = ESO[0].T * ( angular_acceleration_error.x * P3.x )/ESO[0].b;outPitch = ESO[1].T * ( angular_acceleration_error.y * P3.y )/ESO[1].b;//outYaw = ESO[2].T * ( angular_acceleration_error.z * P.z )/ESO[2].b;outYaw = ( target_angular_acceleration.z ) / ESO[2].b;}// outRoll_filted += 80 * h * ( outRoll - outRoll_filted );
// outPitch_filted += 80 * h * ( outPitch - outPitch_filted );
// outYaw_filted += 80 * h * ( outYaw - outYaw_filted );if( inFlight ){double logbuf[10];logbuf[0] = target_angular_rate_body.x;logbuf[1] = AngularRateCtrl.x;logbuf[2] = angular_rate_ESO.x;logbuf[3] = target_angular_acceleration.x;logbuf[4] = angular_acceleration_ESO.x;logbuf[5] = ESO[0].get_EsMainPower();logbuf[6] = outRoll;logbuf[7] = disturbance.x;logbuf[8] = ESO[0].u;SDLog_Msg_DebugVect( "att", logbuf, 9 );}switch( cfg.UAVType ){case UAVType_Rotor4_X:ctrl_Attitude_MultiRotor_X4_PWM( outRoll , outPitch , outYaw );break; case UAVType_Rotor6_X:ctrl_Attitude_MultiRotor_X6_PWM( outRoll , outPitch , outYaw );break;case UAVType_Rotor8_X:ctrl_Attitude_MultiRotor_X8_PWM( outRoll , outPitch , outYaw );break;
//
// case UAVType_Rotor4_C:
// ctrl_Attitude_MultiRotor_C4_PWM( outRoll , outPitch , outYaw );
// break;
//
// case UAVType_Rotor42_C:
// ctrl_Attitude_MultiRotor_C42_PWM( outRoll , outPitch , outYaw );
// break;case UAVType_Rotor6_S1:ctrl_Attitude_MultiRotor_S6_1_PWM( outRoll , outPitch , outYaw );break;default:PWM_PullDownAll();break;}
}//电机非线性输出 线性修正
static inline void throttle_nonlinear_compensation( double out[8] )
{double output_minimum_throttle = cfg.STThrottle[0];double output_range = 100.0f - output_minimum_throttle;double inv_output_range = 1.0 / output_range;//a:非线性因子(0-1)//m:最大油门比例(0.6-1)//设油门-力曲线方程为://F = kx^2 + (1-a)x ( 0<=x<=m F最大值为1 )//x = m时:km^2 + (1-a)m = 1//得k = ( 1 - (1-a)m ) / m^2//a_1 = a - 1//Hk = 1 / 2k//K4 = 4* k//解方程组:kx^2 + (1-a)x = out//得到的x即为线性化后的输出double _lift_max = cfg.FullThrRatio[0];double a_1 = cfg.NonlinearFactor[0] - 1;double k = ( 1 + a_1*_lift_max ) / (_lift_max*_lift_max);double Hk = 1.0f / (2*k);double K4 = 4 * k;for( uint8_t i = 0; i < 8; ++i ){if( out[i] > output_minimum_throttle - 0.1f ){out[i] -= output_minimum_throttle;out[i] *= inv_output_range;if( out[i] < 0 )out[i] = 0;out[i] = Hk*( a_1 + safe_sqrt( a_1*a_1 + K4*out[i] ) );out[i] *= output_range;out[i] += output_minimum_throttle; }elseout[i] = 0;}
}//四旋翼X模式
static void ctrl_Attitude_MultiRotor_X4_PWM( double outRoll , double outPitch , double outYaw )
{double rotor_output[8] = {0,0,0,0,-200,-200,-200,-200};double output_minimum_throttle = cfg.STThrottle[0];
// if( get_current_Receiver()->data[0] < 5 )
// {
// PWM_PullDownAll();
// update_output_throttle( 0 , 1.0f/CtrlRateHz );
// return;
// } if( throttle < output_minimum_throttle - 0.1f ){PWM_PullDownAll();update_output_throttle( 0 , 1.0/CtrlRateHz );return;} double output_throttle = throttle;double output_midpoint = ( 100.0f - output_minimum_throttle ) / 2;
// double cos_angle = lean_cos;
// if( cos_angle < 0.5f )cos_angle = 0.5f;
// output_throttle = throttle / cos_angle;/*pitch roll 输出限幅*///如果需要的pitch roll输出超出当前油门能提供的输出范围//调整油门获得尽量满足pitch roll输出rotor_output[0] = -outPitch+outRoll;rotor_output[1] = +outPitch+outRoll; rotor_output[2] = +outPitch-outRoll;rotor_output[3] = -outPitch-outRoll;double output_max;double output_min ;output_max = rotor_output[0];for( int i = 1 ; i < 4 ; ++i ){if( rotor_output[i] > output_max ) output_max = rotor_output[i];}double max_allow_output = 100.0f - output_throttle;double min_allow_output = output_minimum_throttle - output_throttle; double allow_ouput_range;if( max_allow_output < -min_allow_output ){//降低油门确保姿态输出allow_ouput_range = max_allow_output;if( output_max > allow_ouput_range ){if( output_max > output_midpoint ){output_throttle = output_midpoint + output_minimum_throttle;allow_ouput_range = output_midpoint;}else{output_throttle = 100.0f - output_max;allow_ouput_range = output_max;}}}else{//抬高油门保证姿态输出allow_ouput_range = -min_allow_output;if( output_max > allow_ouput_range ){double hover_throttle_force = hover_throttle - output_minimum_throttle;double max_allowed_output_range = ( hover_throttle_force > output_midpoint ? output_midpoint : hover_throttle_force ) * 0.95;// double hover_throttle_force = hover_throttle - output_minimum_throttle;
// double max_allowed_throttle_force = output_throttle - output_minimum_throttle;
// max_allowed_throttle_force += hover_throttle_force*0.3;
// double max_allowed_output_range = ( max_allowed_throttle_force > output_midpoint ? output_midpoint : max_allowed_throttle_force );if( max_allowed_output_range < output_throttle - output_minimum_throttle )max_allowed_output_range = output_throttle - output_minimum_throttle;double max_allowed_throttle = max_allowed_output_range + output_minimum_throttle;if( output_max > max_allowed_output_range ){output_throttle = max_allowed_throttle;allow_ouput_range = max_allowed_output_range;}else{output_throttle = output_minimum_throttle + output_max;allow_ouput_range = output_max;}}}//输出限幅修正if( output_max > allow_ouput_range ){double scale = allow_ouput_range / output_max;rotor_output[0] *= scale;rotor_output[1] *= scale;rotor_output[2] *= scale;rotor_output[3] *= scale;Roll_u = outRoll * scale;Pitch_u = outPitch * scale;} else{Roll_u = outRoll;Pitch_u = outPitch;}/*pitch roll 输出限幅*//*yaw output 输出限幅*///for Yaw control, it has the lowest priority//lower output to ensure attitude control and alt control output_max = 0.0f;output_min = 100.0f;/*find min yaw_scale*/double yaw_scale = 1.0f;for( int i = 0 ; i < 4 ; ++i ){double current_out_yaw = ( (i&1) == 1 ) ? outYaw : -outYaw;double current_rotor_output = output_throttle + rotor_output[i];max_allow_output = 100.0f - current_rotor_output;min_allow_output = output_minimum_throttle - current_rotor_output;if( current_out_yaw > max_allow_output + 0.01f ){double new_yaw_scale = max_allow_output / current_out_yaw;if( new_yaw_scale < yaw_scale ) yaw_scale = new_yaw_scale;}else if( current_out_yaw < min_allow_output - 0.01f ){double new_yaw_scale = min_allow_output / current_out_yaw;if( new_yaw_scale < yaw_scale ) yaw_scale = new_yaw_scale;}}/*find min yaw_scale*///lower yaw output to ensure attitude control and alt controlif( yaw_scale < 0 )yaw_scale = 0;outYaw *= yaw_scale;Yaw_u = outYaw;/*yaw output 输出限幅*/update_output_throttle( output_throttle , 1.0/CtrlRateHz );rotor_output[0] += output_throttle-outYaw;rotor_output[1] += output_throttle+outYaw;rotor_output[2] += output_throttle-outYaw;rotor_output[3] += output_throttle+outYaw;throttle_nonlinear_compensation( rotor_output );PWM_Out( rotor_output );
}//六旋翼X模式
static void ctrl_Attitude_MultiRotor_X6_PWM( double outRoll , double outPitch , double outYaw )
{double rotor_output[8] = {0,0,0,0,0,0,-200,-200};double output_minimum_throttle = cfg.STThrottle[0];
// if( get_current_Receiver()->data[0] < 5 )
// {
// PWM_PullDownAll();
// update_output_throttle( 0 , 1.0f/CtrlRateHz );
// return;
// } if( throttle < output_minimum_throttle - 0.1f ){PWM_PullDownAll();update_output_throttle( 0 , 1.0/CtrlRateHz );return;}double output_throttle = throttle;double output_midpoint = ( 100.0f - output_minimum_throttle ) / 2;
// float cos_angle = lean_cos;
// if( cos_angle < 0.5f )cos_angle = 0.5f;
// output_throttle = throttle / cos_angle;/*pitch roll 输出限幅*///如果需要的pitch roll输出超出当前油门能提供的输出范围//调整油门获得尽量满足pitch roll输出double RollS = outRoll * 1.1547005383792515290182975610039f;double half_outRoll = 0.5f * RollS;rotor_output[0] = -outPitch+half_outRoll;rotor_output[1] = RollS;rotor_output[2] = +outPitch+half_outRoll;rotor_output[3] = +outPitch-half_outRoll;rotor_output[4] = -RollS;rotor_output[5] = -outPitch-half_outRoll;double output_max;double output_min ;output_max = rotor_output[0];for( int i = 1 ; i < 6 ; ++i ){if( rotor_output[i] > output_max ) output_max = rotor_output[i];}double max_allow_output = 100.0f - output_throttle;double min_allow_output = output_minimum_throttle - output_throttle; double allow_ouput_range;if( max_allow_output < -min_allow_output ){//降低油门确保姿态输出allow_ouput_range = max_allow_output;if( output_max > allow_ouput_range ){if( output_max > output_midpoint ){output_throttle = output_midpoint + output_minimum_throttle;allow_ouput_range = output_midpoint;}else{output_throttle = 100.0f - output_max;allow_ouput_range = output_max;}}}else{allow_ouput_range = -min_allow_output;if( output_max > allow_ouput_range ){double hover_throttle_force = hover_throttle - output_minimum_throttle;double max_allowed_output_range = ( hover_throttle_force > output_midpoint ? output_midpoint : hover_throttle_force ) * 0.8f;if( max_allowed_output_range < output_throttle - output_minimum_throttle )max_allowed_output_range = output_throttle - output_minimum_throttle;double max_allowed_throttle = max_allowed_output_range + output_minimum_throttle;if( output_max > max_allowed_output_range ){output_throttle = max_allowed_throttle;allow_ouput_range = max_allowed_output_range;}else{output_throttle = output_minimum_throttle + output_max;allow_ouput_range = output_max;}}}if( output_max > allow_ouput_range ){double scale = allow_ouput_range / output_max;rotor_output[0] *= scale;rotor_output[1] *= scale;rotor_output[2] *= scale;rotor_output[3] *= scale;rotor_output[4] *= scale;rotor_output[5] *= scale;Roll_u = outRoll * scale;Pitch_u = outPitch * scale;} else{Roll_u = outRoll;Pitch_u = outPitch;}/*pitch roll 输出限幅*//*yaw output 输出限幅*///for Yaw control, it has the lowest priority//lower output to ensure attitude control and alt control output_max = 0.0f;output_min = 100.0f;/*find min yaw_scale*/double yaw_scale = 1.0f;for( int i = 0 ; i < 6 ; ++i ){double current_out_yaw = ( (i&1) == 1 ) ? outYaw : -outYaw;double current_rotor_output = output_throttle + rotor_output[i];max_allow_output = 100.0f - current_rotor_output;min_allow_output = output_minimum_throttle - current_rotor_output;if( current_out_yaw > max_allow_output + 0.01f ){double new_yaw_scale = max_allow_output / current_out_yaw;if( new_yaw_scale < yaw_scale ) yaw_scale = new_yaw_scale;}else if( current_out_yaw < min_allow_output - 0.01f ){double new_yaw_scale = min_allow_output / current_out_yaw;if( new_yaw_scale < yaw_scale ) yaw_scale = new_yaw_scale;}}/*find min yaw_scale*///lower yaw output to ensure attitude control and alt controlif( yaw_scale < 0 )yaw_scale = 0;outYaw *= yaw_scale;Yaw_u = outYaw;/*yaw output 输出限幅*/update_output_throttle( output_throttle , 1.0/CtrlRateHz );rotor_output[0] += output_throttle-outYaw;rotor_output[1] += output_throttle+outYaw;rotor_output[2] += output_throttle-outYaw;rotor_output[3] += output_throttle+outYaw;rotor_output[4] += output_throttle-outYaw;rotor_output[5] += output_throttle+outYaw;throttle_nonlinear_compensation( rotor_output );PWM_Out( rotor_output );
}//六旋翼异构
/*o--oo--oo--o
*/
static void ctrl_Attitude_MultiRotor_S6_1_PWM( double outRoll , double outPitch , double outYaw )
{double rotor_output[8] = {0,0,0,0,0,0,-200,-200};double output_minimum_throttle = cfg.STThrottle[0];
// if( get_current_Receiver()->data[0] < 5 )
// {
// PWM_PullDownAll();
// update_output_throttle( 0 , 1.0f/CtrlRateHz );
// return;
// } if( throttle < output_minimum_throttle - 0.1f ){PWM_PullDownAll();update_output_throttle( 0 , 1.0/CtrlRateHz );return;}double output_throttle = throttle;double output_midpoint = ( 100.0f - output_minimum_throttle ) / 2;
// float cos_angle = lean_cos;
// if( cos_angle < 0.5f )cos_angle = 0.5f;
// output_throttle = throttle / cos_angle;/*pitch roll 输出限幅*///如果需要的pitch roll输出超出当前油门能提供的输出范围//调整油门获得尽量满足pitch roll输出double RollS = outRoll * 1.732;double half_outRoll = 0.5f * RollS;rotor_output[0] = -outPitch+half_outRoll;rotor_output[1] = RollS;rotor_output[2] = +outPitch+half_outRoll;rotor_output[3] = +outPitch-half_outRoll;rotor_output[4] = -RollS;rotor_output[5] = -outPitch-half_outRoll;double output_max;double output_min ;output_max = rotor_output[0];for( int i = 1 ; i < 6 ; ++i ){if( rotor_output[i] > output_max ) output_max = rotor_output[i];}double max_allow_output = 100.0f - output_throttle;double min_allow_output = output_minimum_throttle - output_throttle; double allow_ouput_range;if( max_allow_output < -min_allow_output ){//降低油门确保姿态输出allow_ouput_range = max_allow_output;if( output_max > allow_ouput_range ){if( output_max > output_midpoint ){output_throttle = output_midpoint + output_minimum_throttle;allow_ouput_range = output_midpoint;}else{output_throttle = 100.0f - output_max;allow_ouput_range = output_max;}}}else{allow_ouput_range = -min_allow_output;if( output_max > allow_ouput_range ){double hover_throttle_force = hover_throttle - output_minimum_throttle;double max_allowed_output_range = ( hover_throttle_force > output_midpoint ? output_midpoint : hover_throttle_force ) * 0.8f;if( max_allowed_output_range < output_throttle - output_minimum_throttle )max_allowed_output_range = output_throttle - output_minimum_throttle;double max_allowed_throttle = max_allowed_output_range + output_minimum_throttle;if( output_max > max_allowed_output_range ){output_throttle = max_allowed_throttle;allow_ouput_range = max_allowed_output_range;}else{output_throttle = output_minimum_throttle + output_max;allow_ouput_range = output_max;}}}if( output_max > allow_ouput_range ){double scale = allow_ouput_range / output_max;rotor_output[0] *= scale;rotor_output[1] *= scale;rotor_output[2] *= scale;rotor_output[3] *= scale;rotor_output[4] *= scale;rotor_output[5] *= scale;Roll_u = outRoll * scale;Pitch_u = outPitch * scale;} else{Roll_u = outRoll;Pitch_u = outPitch;}/*pitch roll 输出限幅*//*yaw output 输出限幅*///for Yaw control, it has the lowest priority//lower output to ensure attitude control and alt control output_max = 0.0f;output_min = 100.0f;/*find min yaw_scale*/double yaw_scale = 1.0f;for( int i = 0 ; i < 6 ; ++i ){double current_out_yaw = ( (i&1) == 1 ) ? 0.5*outYaw : -0.5*outYaw;if( i==1 || i==4 )current_out_yaw *= 2;double current_rotor_output = output_throttle + rotor_output[i];max_allow_output = 100.0f - current_rotor_output;min_allow_output = output_minimum_throttle - current_rotor_output;if( current_out_yaw > max_allow_output + 0.01f ){double new_yaw_scale = max_allow_output / current_out_yaw;if( new_yaw_scale < yaw_scale ) yaw_scale = new_yaw_scale;}else if( current_out_yaw < min_allow_output - 0.01f ){double new_yaw_scale = min_allow_output / current_out_yaw;if( new_yaw_scale < yaw_scale ) yaw_scale = new_yaw_scale;}}/*find min yaw_scale*///lower yaw output to ensure attitude control and alt controlif( yaw_scale < 0 )yaw_scale = 0;outYaw *= yaw_scale;Yaw_u = outYaw;/*yaw output 输出限幅*/update_output_throttle( output_throttle , 1.0/CtrlRateHz );rotor_output[0] += output_throttle-outYaw;rotor_output[1] += output_throttle+outYaw;rotor_output[2] += output_throttle-outYaw;rotor_output[3] += output_throttle+outYaw;rotor_output[4] += output_throttle-outYaw;rotor_output[5] += output_throttle+outYaw;throttle_nonlinear_compensation( rotor_output );PWM_Out( rotor_output );
}//八旋翼X模式
static void ctrl_Attitude_MultiRotor_X8_PWM( double outRoll , double outPitch , double outYaw )
{double rotor_output[8] = {0,0,0,0,0,0,0,0};double output_minimum_throttle = cfg.STThrottle[0];
// if( get_current_Receiver()->data[0] < 5 )
// {
// PWM_PullDownAll();
// update_output_throttle( 0 , 1.0f/CtrlRateHz );
// return;
// } if( throttle < output_minimum_throttle - 0.1f ){PWM_PullDownAll();update_output_throttle( 0 , 1.0/CtrlRateHz );return;}double output_throttle = throttle;double output_midpoint = ( 100.0f - output_minimum_throttle ) / 2;
// float cos_angle = lean_cos;
// if( cos_angle < 0.5f )cos_angle = 0.5f;
// output_throttle = throttle / cos_angle;/*pitch roll 输出限幅*///如果需要的pitch roll输出超出当前油门能提供的输出范围//调整油门获得尽量满足pitch roll输出rotor_output[0] = -outPitch+outRoll;rotor_output[1] = -outPitch+outRoll;rotor_output[2] = +outPitch+outRoll;rotor_output[3] = +outPitch+outRoll;rotor_output[4] = +outPitch-outRoll;rotor_output[5] = +outPitch-outRoll;rotor_output[6] = -outPitch-outRoll;rotor_output[7] = -outPitch-outRoll;double output_max;double output_min ;output_max = rotor_output[0];for( int i = 1 ; i < 8 ; ++i ){if( rotor_output[i] > output_max ) output_max = rotor_output[i];}double max_allow_output = 100.0f - output_throttle;double min_allow_output = output_minimum_throttle - output_throttle; double allow_ouput_range;if( max_allow_output < -min_allow_output ){//降低油门确保姿态输出allow_ouput_range = max_allow_output;if( output_max > allow_ouput_range ){if( output_max > output_midpoint ){output_throttle = output_midpoint + output_minimum_throttle;allow_ouput_range = output_midpoint;}else{output_throttle = 100.0f - output_max;allow_ouput_range = output_max;}}}else{allow_ouput_range = -min_allow_output;if( output_max > allow_ouput_range ){double hover_throttle_force = hover_throttle - output_minimum_throttle;double max_allowed_output_range = ( hover_throttle_force > output_midpoint ? output_midpoint : hover_throttle_force ) * 0.8f;if( max_allowed_output_range < output_throttle - output_minimum_throttle )max_allowed_output_range = output_throttle - output_minimum_throttle;double max_allowed_throttle = max_allowed_output_range + output_minimum_throttle;if( output_max > max_allowed_output_range ){output_throttle = max_allowed_throttle;allow_ouput_range = max_allowed_output_range;}else{output_throttle = output_minimum_throttle + output_max;allow_ouput_range = output_max;}}}if( output_max > allow_ouput_range ){double scale = allow_ouput_range / output_max;rotor_output[0] *= scale;rotor_output[1] *= scale;rotor_output[2] *= scale;rotor_output[3] *= scale;rotor_output[4] *= scale;rotor_output[5] *= scale;rotor_output[6] *= scale;rotor_output[7] *= scale;Roll_u = outRoll * scale;Pitch_u = outPitch * scale;} else{Roll_u = outRoll;Pitch_u = outPitch;}/*pitch roll 输出限幅*//*yaw output 输出限幅*///for Yaw control, it has the lowest priority//lower output to ensure attitude control and alt control output_max = 0.0f;output_min = 100.0f;/*find min yaw_scale*/double yaw_scale = 1.0f;for( int i = 0 ; i < 8 ; ++i ){double current_out_yaw = ( (i&1) == 1 ) ? outYaw : -outYaw;double current_rotor_output = output_throttle + rotor_output[i];max_allow_output = 100.0f - current_rotor_output;min_allow_output = output_minimum_throttle - current_rotor_output;if( current_out_yaw > max_allow_output + 0.01f ){double new_yaw_scale = max_allow_output / current_out_yaw;if( new_yaw_scale < yaw_scale ) yaw_scale = new_yaw_scale;}else if( current_out_yaw < min_allow_output - 0.01f ){double new_yaw_scale = min_allow_output / current_out_yaw;if( new_yaw_scale < yaw_scale ) yaw_scale = new_yaw_scale;}}/*find min yaw_scale*///lower yaw output to ensure attitude control and alt controlif( yaw_scale < 0 )yaw_scale = 0;outYaw *= yaw_scale;Yaw_u = outYaw;/*yaw output 输出限幅*/update_output_throttle( output_throttle , 1.0/CtrlRateHz );rotor_output[0] += output_throttle-outYaw;rotor_output[1] += output_throttle+outYaw;rotor_output[2] += output_throttle-outYaw;rotor_output[3] += output_throttle+outYaw;rotor_output[4] += output_throttle-outYaw;rotor_output[5] += output_throttle+outYaw;rotor_output[6] += output_throttle-outYaw;rotor_output[7] += output_throttle+outYaw;throttle_nonlinear_compensation( rotor_output );PWM_Out( rotor_output );
}void init_Ctrl_Attitude()
{//注册参数cfg.UAVType = UAVType_Rotor4_X;cfg.STThrottle[0] = 10;cfg.NonlinearFactor[0] = 0.45;cfg.FullThrRatio[0] = 0.95;cfg.T[0] = 0.1;cfg.b[0] = 5.5; cfg.b[2] = 5.5; cfg.b[4] = 1.0;cfg.TD4_P1[0] = 15; cfg.TD4_P1[2] = 15; cfg.TD4_P1[4] = 2;cfg.TD4_P2[0] = 15; cfg.TD4_P2[2] = 15; cfg.TD4_P2[4] = 5;cfg.TD4_P3[0] = 25; cfg.TD4_P3[2] = 25; cfg.TD4_P3[4] = 25;cfg.TD4_P4[0] = 25; cfg.TD4_P4[2] = 25; cfg.TD4_P4[4] = 25;cfg.P1[0] = 5; cfg.P1[2] = 5; cfg.P1[4] = 2;cfg.P2[0] = 10; cfg.P2[2] = 10; cfg.P2[4] = 5;cfg.P3[0] = 25; cfg.P3[2] = 25; cfg.P3[4] = 25;cfg.P4[0] = 15; cfg.P4[2] = 15; cfg.P4[4] = 15;cfg.beta2[0] = 30;cfg.maxLean[0] = 35;cfg.maxRPSp[0] = 350;cfg.maxRPAcc[0] = 7000;cfg.maxYSp[0] = 80;cfg.maxYAcc[0] = 1000;MAV_PARAM_TYPE param_types[] = {MAV_PARAM_TYPE_UINT8 , //UAV TypeMAV_PARAM_TYPE_REAL32 , //起转油门MAV_PARAM_TYPE_REAL32 , //非线性参数MAV_PARAM_TYPE_REAL32 , //满油门比例MAV_PARAM_TYPE_REAL32 , //TMAV_PARAM_TYPE_REAL32 ,MAV_PARAM_TYPE_REAL32 ,MAV_PARAM_TYPE_REAL32 , //b[3]MAV_PARAM_TYPE_REAL32 ,MAV_PARAM_TYPE_REAL32 ,MAV_PARAM_TYPE_REAL32 , //TD4_P1[3]MAV_PARAM_TYPE_REAL32 ,MAV_PARAM_TYPE_REAL32 ,MAV_PARAM_TYPE_REAL32 , //TD4_P2[3]MAV_PARAM_TYPE_REAL32 ,MAV_PARAM_TYPE_REAL32 ,MAV_PARAM_TYPE_REAL32 , //TD4_P3[3]MAV_PARAM_TYPE_REAL32 ,MAV_PARAM_TYPE_REAL32 ,MAV_PARAM_TYPE_REAL32 , //TD4_P4[3]MAV_PARAM_TYPE_REAL32 ,MAV_PARAM_TYPE_REAL32 ,MAV_PARAM_TYPE_REAL32 , //P1[3]MAV_PARAM_TYPE_REAL32 ,MAV_PARAM_TYPE_REAL32 ,MAV_PARAM_TYPE_REAL32 , //P2[3]MAV_PARAM_TYPE_REAL32 ,MAV_PARAM_TYPE_REAL32 ,MAV_PARAM_TYPE_REAL32 , //P3[3]MAV_PARAM_TYPE_REAL32 ,MAV_PARAM_TYPE_REAL32 ,MAV_PARAM_TYPE_REAL32 , //P4[3]MAV_PARAM_TYPE_REAL32 , //beta2MAV_PARAM_TYPE_REAL32 , //最大倾斜角MAV_PARAM_TYPE_REAL32 , //maxRPSpMAV_PARAM_TYPE_REAL32 , //maxRPAccMAV_PARAM_TYPE_REAL32 , //maxYSpMAV_PARAM_TYPE_REAL32 , //maxYAcc};SName param_names[] = {"AC_UAVType" , //UAV Type"AC_STThr" , //起转油门"AC_NonlinF" , //非线性参数"AC_FullThrR" , //满油门比例"AC_T" , //T"AC_Roll_b" ,"AC_Pitch_b" ,"AC_Yaw_b" , //b[3]"AC_Roll_TD4P1" ,"AC_Pitch_TD4P1" ,"AC_Yaw_TD4P1" , //TD4_P1[3]"AC_Roll_TD4P2" ,"AC_Pitch_TD4P2" ,"AC_Yaw_TD4P2" , //TD4_P2[3]"AC_Roll_TD4P3" ,"AC_Pitch_TD4P3" ,"AC_Yaw_TD4P3" , //TD4_P3[3]"AC_Roll_TD4P4" ,"AC_Pitch_TD4P4" ,"AC_Yaw_TD4P4" , //TD4_P4[3]"AC_Roll_P1" ,"AC_Pitch_P1" ,"AC_Yaw_P1" , //P1[3]"AC_Roll_P2" ,"AC_Pitch_P2" ,"AC_Yaw_P2" , //P2[3]"AC_Roll_P3" ,"AC_Pitch_P3" ,"AC_Yaw_P3" , //P3[3]"AC_Roll_P4" ,"AC_Pitch_P4" ,"AC_Yaw_P4" , //P4[3]"AC_Beta2" , //beta2"AC_maxLean" , //最大倾斜角"AC_maxRPSp" , //最大Pitch Roll速度"AC_maxRPAcc" , //最大Pitch Roll加速度"AC_maxYSp" , //最大偏航速度"AC_maxYAcc" , //最大偏航加速度};ParamGroupRegister( "AttCtrl", 2, 38, param_types, param_names, (uint64_t*)&cfg );
}
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
相关文章
- 苹果macOS10.15.7新版本下的SecureFX与SecureCRT破解后显示文件受损解决方法
第一步先下载 https://www.vandyke.com/download/securecrt/4.0/index.html 第二步安装下载后的程序 第三步运行原本程序,两个都要运行,然后关闭。 第四步运行破解命令 sudo perl securefx_linux_crack.pl /Applications/SecureFX.app/Contents/MacOS…...
2024/5/4 17:38:51 - Spring基础--完全抛去xml配置文件的spring自带相应式事务控制
前面从XML配置到注解配置,注解配置链接,但注解配置并没有完全抛掉bean.xml配置文件。 1、创建主配置文件 springConfiguration.java /* * spring的配置类,相当于bean.xml * */ Configuration ComponentScan("org.example") // 配置…...
2024/4/25 3:06:13 - vue3.0vue-router在3.0版本以上element ui导航栏重复点击报错解决办法
Vue.js 项目控制台报错: Uncaught (in promise) NavigationDuplicated: Avoided redundant navigation to current location: "/user/student". 问题原因:多次点击跳转同一路由是不被允许的(版本原因) 解决方案&#x…...
2024/5/4 22:17:25 - 7-6 输出带框文字
输出带框文字 输入格式: 本题无输入 输出格式: 按照下列格式输出带框文字。 Welcome #include<stdio.h> int main() {printf("************\n"); printf(" Welcome\n");printf("************");return 0; }...
2024/5/3 8:06:05 - oracle锁表问题解决
查看是哪个session引起的 select b.username,b.sid,b.serial#,logon_time from v$locked_object a,v$session b where a.session_id b.sid order by b.logon_time; 根据查找的sid和serial执行如下语句: alter system kill session sid,serial#; 原文:https://b…...
2024/4/15 11:59:12 - pm2启动jar包(SpringBoot)
pm2启动jar包 简介PM2: 是node进程管理工具,可以利用它来简化很多node应用管理的繁琐任务,如性能监控、自动重启、负载均衡等,而且使用非常简单。 Linux中全局安装PM2: #npm是node.js命令,自行百度安装…...
2024/4/28 10:57:22 - 职业年金退休能拿多少?怎么算的?
职业年金退休能拿多少?怎么算的?其实朋友可能有点误会,没有真正弄清楚职业年金的含义和内容,职业年金不属于退休金,而是一种补充性的养老保险制度。所谓补充性的,就还是要以基本的养老保险为主,…...
2024/5/3 10:56:19 - 日常记录
安装使用gitbook与排坑 安装 # 需要先拥有nodejs npm # git # 安装脚手架 npm install gitbook-cli -g # 安装gitbook所依赖的一些plugins gitbook install # 在所需要的项目目录下启动 gitbook server .排坑 node和npm的版本太新,影响安装gitbook,先…...
2024/5/3 8:00:44 - 相关性 与 相干性 那些事
相关性 与 相干性 那些事 1、相关性 相关性,是指两个变量的关联程度。一般地,从散点图上可以观察到两个变量有以下三种关系之一:两变量正相关、负相关、不相关。如果一个变量高的值对应于另一个变量高的值,相似地,低…...
2024/4/18 18:25:35 - 蓝桥杯 试题 历届试题 小数第n位
题目链接:http://lx.lanqiao.cn/problem.page?gpidT456 题意: 问题描述 我们知道,整数做除法时,有时得到有限小数,有时得到无限循环小数。 如果我们把有限小数的末尾加上无限多个0,它们就有了统一…...
2024/4/28 6:12:04 - cf672
A. Cubes Sorting 题意思路:看一下是不是降序即可 代码: #include<iostream> #include<queue> #include<stack> #include<cstring> #include<stdlib.h> #include<cstdio> #include<iostream> #include<algorithm>…...
2024/4/26 14:29:16 - 113. 路径总和 II
给定一个二叉树和一个目标和,找到所有从根节点到叶子节点路径总和等于给定目标和的路径。 说明: 叶子节点是指没有子节点的节点。 示例: 给定如下二叉树,以及目标和 sum 22, 5/ \4 8/ / \11 13 4/ \ / \7 2 5 1返回: [[5…...
2024/4/25 4:26:46 - 十级孤独你能承受几级?
作为群居动物,有很多人都是“没人陪不能出门星人”,不论做啥都希望有人陪。但偏偏有人就出了这么一个“寂寞忍受力排行榜”,一下这些事情你一个人做过几件呢?你能忍受到第几级呢? 都说越长大越孤独,当你不…...
2024/5/3 7:58:19 - ios私钥证书的创建流程
生成ios私钥证书需要使用mac电脑,生成csr文件,然后在苹果开发者中心创建证书,生成cer证书,cer证书就可以用来开发和打包。假如是H5应用,则需要将cer文件下载下来,生成P12文件,再进行打包。 但是…...
2024/5/3 9:38:27 - Redis系列:单机主从模式搭建
无论哪种中间件的搭建,正常主从模式搭建需要搭建在两台不同的服务器上才是正规的主从搭建模式。因为由于资源的限制,今天来演示一下在同一台服务器上,基于端口不一致搭建Redis的单机主从模式。 如果是不同的Linux服务器搭建Redis主从模式&…...
2024/5/2 9:50:25 - MyBatis应用分析与最佳实践
1)为什么要用MyBatis? (1)JavaEE的规范,用JDBC (2)JDBC的问题 代码重复:和业务逻辑无关的代码,十分重复。 结果集处理太复杂: 需要啊自动转化为Pojo对象,十分麻烦。 连接管理: …...
2024/4/7 9:23:04 - EffectiveC++ 条款51:编写new和delete时需固守常规
...
2024/4/21 23:44:51 - 7-8 3人分糖果
3人分糖果 输出格式: 在一行内显示以下结果。注意行末除了换行符不能有任何多余字符。 10 8 5 #include<stdio.h> int main() {int a8,b9,c10;a/3;ba;ca;b/3;ab;cb;c/3;ac;bc;printf("%d %d %d",a,b,c); }...
2024/4/7 9:23:02 - 反思自己问题分享
学习上出现的问题 一直在学习却忘了放慢脚步,导致学的太快、不扎实。JavaSE浅部知识确实很简单,如果去深度刨析里面更深一层知识后会花很长时间,现在我们掌握的 SE 知识点只能算是会用。学过后没有过多去实践,找各种借口翻篇。如…...
2024/4/27 11:14:47 - 代理模式:静态代理&动态代理
代理模式 代理模式: SpringAOP的底层【SpringAOP和SpringMVC】 静态代理 角色: 抽象角色: 一般使用接口或者抽象类来实现真实角色: 被代理的角色代理角色:代理真实角色 ; 代理真实角色后 , 一般会做一些附属的操作…...
2024/5/3 10:03:16
最新文章
- gateway linux远程后端 连接报错:“exit code: 1“
gateway linux远程后端 连接时报错:“exit code: 1” 问题细节 之前使用gateway连接过,但某次连接时报错日志如下,面板会弹出信息,也可在C:\Users\YJM\AppData\Local\JetBrains\IntelliJIdea2023.3\log\gateway\20240504-171145…...
2024/5/4 23:38:58 - 梯度消失和梯度爆炸的一些处理方法
在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言,在此感激不尽。 权重和梯度的更新公式如下: w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...
2024/3/20 10:50:27 - 如何在极狐GitLab 使用Docker 仓库功能
本文作者:徐晓伟 GitLab 是一个全球知名的一体化 DevOps 平台,很多人都通过私有化部署 GitLab 来进行源代码托管。极狐GitLab 是 GitLab 在中国的发行版,专门为中国程序员服务。可以一键式部署极狐GitLab。 本文主要讲述了如何在[极狐GitLab…...
2024/5/4 7:46:48 - Java深度优先搜索DFS(含面试大厂题和源码)
深度优先搜索(Depth-First Search,简称DFS)是一种用于遍历或搜索树或图的算法。DFS 通过沿着树的深度来遍历节点,尽可能深地搜索树的分支。当节点v的所在边都已被探寻过,搜索将回溯到发现节点v的那条边的起始节点。这个…...
2024/5/3 10:02:23 - 备战蓝桥杯Day37 - 真题 - 特殊日期
一、题目描述 思路: 1、统计2000年到2000000年的日期,肯定是需要遍历 2、闰年的2月是29天,非闰年的2月是28天。我们需要判断这一年是否是闰年。 1、3、5、7、8、10、12月是31天,4、6、9、11月是30天。 3、年份yy是月份mm的倍数…...
2024/5/4 13:34:29 - 416. 分割等和子集问题(动态规划)
题目 题解 class Solution:def canPartition(self, nums: List[int]) -> bool:# badcaseif not nums:return True# 不能被2整除if sum(nums) % 2 ! 0:return False# 状态定义:dp[i][j]表示当背包容量为j,用前i个物品是否正好可以将背包填满ÿ…...
2024/5/4 12:05:22 - 【Java】ExcelWriter自适应宽度工具类(支持中文)
工具类 import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellType; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet;/*** Excel工具类** author xiaoming* date 2023/11/17 10:40*/ public class ExcelUti…...
2024/5/4 11:23:32 - Spring cloud负载均衡@LoadBalanced LoadBalancerClient
LoadBalance vs Ribbon 由于Spring cloud2020之后移除了Ribbon,直接使用Spring Cloud LoadBalancer作为客户端负载均衡组件,我们讨论Spring负载均衡以Spring Cloud2020之后版本为主,学习Spring Cloud LoadBalance,暂不讨论Ribbon…...
2024/5/4 14:46:16 - TSINGSEE青犀AI智能分析+视频监控工业园区周界安全防范方案
一、背景需求分析 在工业产业园、化工园或生产制造园区中,周界防范意义重大,对园区的安全起到重要的作用。常规的安防方式是采用人员巡查,人力投入成本大而且效率低。周界一旦被破坏或入侵,会影响园区人员和资产安全,…...
2024/5/3 16:00:51 - VB.net WebBrowser网页元素抓取分析方法
在用WebBrowser编程实现网页操作自动化时,常要分析网页Html,例如网页在加载数据时,常会显示“系统处理中,请稍候..”,我们需要在数据加载完成后才能继续下一步操作,如何抓取这个信息的网页html元素变化&…...
2024/5/4 12:10:13 - 【Objective-C】Objective-C汇总
方法定义 参考:https://www.yiibai.com/objective_c/objective_c_functions.html Objective-C编程语言中方法定义的一般形式如下 - (return_type) method_name:( argumentType1 )argumentName1 joiningArgument2:( argumentType2 )argumentName2 ... joiningArgu…...
2024/5/3 21:22:01 - 【洛谷算法题】P5713-洛谷团队系统【入门2分支结构】
👨💻博客主页:花无缺 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 本文由 花无缺 原创 收录于专栏 【洛谷算法题】 文章目录 【洛谷算法题】P5713-洛谷团队系统【入门2分支结构】🌏题目描述🌏输入格…...
2024/5/3 23:17:01 - 【ES6.0】- 扩展运算符(...)
【ES6.0】- 扩展运算符... 文章目录 【ES6.0】- 扩展运算符...一、概述二、拷贝数组对象三、合并操作四、参数传递五、数组去重六、字符串转字符数组七、NodeList转数组八、解构变量九、打印日志十、总结 一、概述 **扩展运算符(...)**允许一个表达式在期望多个参数࿰…...
2024/5/4 14:46:12 - 摩根看好的前智能硬件头部品牌双11交易数据极度异常!——是模式创新还是饮鸩止渴?
文 | 螳螂观察 作者 | 李燃 双11狂欢已落下帷幕,各大品牌纷纷晒出优异的成绩单,摩根士丹利投资的智能硬件头部品牌凯迪仕也不例外。然而有爆料称,在自媒体平台发布霸榜各大榜单喜讯的凯迪仕智能锁,多个平台数据都表现出极度异常…...
2024/5/4 14:46:11 - Go语言常用命令详解(二)
文章目录 前言常用命令go bug示例参数说明 go doc示例参数说明 go env示例 go fix示例 go fmt示例 go generate示例 总结写在最后 前言 接着上一篇继续介绍Go语言的常用命令 常用命令 以下是一些常用的Go命令,这些命令可以帮助您在Go开发中进行编译、测试、运行和…...
2024/5/4 14:46:11 - 用欧拉路径判断图同构推出reverse合法性:1116T4
http://cplusoj.com/d/senior/p/SS231116D 假设我们要把 a a a 变成 b b b,我们在 a i a_i ai 和 a i 1 a_{i1} ai1 之间连边, b b b 同理,则 a a a 能变成 b b b 的充要条件是两图 A , B A,B A,B 同构。 必要性显然࿰…...
2024/5/4 2:14:16 - 【NGINX--1】基础知识
1、在 Debian/Ubuntu 上安装 NGINX 在 Debian 或 Ubuntu 机器上安装 NGINX 开源版。 更新已配置源的软件包信息,并安装一些有助于配置官方 NGINX 软件包仓库的软件包: apt-get update apt install -y curl gnupg2 ca-certificates lsb-release debian-…...
2024/5/4 21:24:42 - Hive默认分割符、存储格式与数据压缩
目录 1、Hive默认分割符2、Hive存储格式3、Hive数据压缩 1、Hive默认分割符 Hive创建表时指定的行受限(ROW FORMAT)配置标准HQL为: ... ROW FORMAT DELIMITED FIELDS TERMINATED BY \u0001 COLLECTION ITEMS TERMINATED BY , MAP KEYS TERMI…...
2024/5/4 12:39:12 - 【论文阅读】MAG:一种用于航天器遥测数据中有效异常检测的新方法
文章目录 摘要1 引言2 问题描述3 拟议框架4 所提出方法的细节A.数据预处理B.变量相关分析C.MAG模型D.异常分数 5 实验A.数据集和性能指标B.实验设置与平台C.结果和比较 6 结论 摘要 异常检测是保证航天器稳定性的关键。在航天器运行过程中,传感器和控制器产生大量周…...
2024/5/4 13:16:06 - --max-old-space-size=8192报错
vue项目运行时,如果经常运行慢,崩溃停止服务,报如下错误 FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory 因为在 Node 中,通过JavaScript使用内存时只能使用部分内存(64位系统&…...
2024/5/4 16:48:41 - 基于深度学习的恶意软件检测
恶意软件是指恶意软件犯罪者用来感染个人计算机或整个组织的网络的软件。 它利用目标系统漏洞,例如可以被劫持的合法软件(例如浏览器或 Web 应用程序插件)中的错误。 恶意软件渗透可能会造成灾难性的后果,包括数据被盗、勒索或网…...
2024/5/4 14:46:05 - JS原型对象prototype
让我简单的为大家介绍一下原型对象prototype吧! 使用原型实现方法共享 1.构造函数通过原型分配的函数是所有对象所 共享的。 2.JavaScript 规定,每一个构造函数都有一个 prototype 属性,指向另一个对象,所以我们也称为原型对象…...
2024/5/4 2:00:16 - C++中只能有一个实例的单例类
C中只能有一个实例的单例类 前面讨论的 President 类很不错,但存在一个缺陷:无法禁止通过实例化多个对象来创建多名总统: President One, Two, Three; 由于复制构造函数是私有的,其中每个对象都是不可复制的,但您的目…...
2024/5/3 22:03:11 - python django 小程序图书借阅源码
开发工具: PyCharm,mysql5.7,微信开发者工具 技术说明: python django html 小程序 功能介绍: 用户端: 登录注册(含授权登录) 首页显示搜索图书,轮播图࿰…...
2024/5/4 9:07:39 - 电子学会C/C++编程等级考试2022年03月(一级)真题解析
C/C++等级考试(1~8级)全部真题・点这里 第1题:双精度浮点数的输入输出 输入一个双精度浮点数,保留8位小数,输出这个浮点数。 时间限制:1000 内存限制:65536输入 只有一行,一个双精度浮点数。输出 一行,保留8位小数的浮点数。样例输入 3.1415926535798932样例输出 3.1…...
2024/5/4 14:46:02 - 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...
解析如下:1、长按电脑电源键直至关机,然后再按一次电源健重启电脑,按F8健进入安全模式2、安全模式下进入Windows系统桌面后,按住“winR”打开运行窗口,输入“services.msc”打开服务设置3、在服务界面,选中…...
2022/11/19 21:17:18 - 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。
%读入6幅图像(每一幅图像的大小是564*564) f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...
2022/11/19 21:17:16 - 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...
win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面,在等待界面中我们需要等待操作结束才能关机,虽然这比较麻烦,但是对系统进行配置和升级…...
2022/11/19 21:17:15 - 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...
有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows,请勿关闭计算机”的提示,要过很久才能进入系统,有的用户甚至几个小时也无法进入,下面就教大家这个问题的解决方法。第一种方法:我们首先在左下角的“开始…...
2022/11/19 21:17:14 - win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...
置信有很多用户都跟小编一样遇到过这样的问题,电脑时发现开机屏幕显现“正在配置Windows Update,请勿关机”(如下图所示),而且还需求等大约5分钟才干进入系统。这是怎样回事呢?一切都是正常操作的,为什么开时机呈现“正…...
2022/11/19 21:17:13 - 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...
Win7系统开机启动时总是出现“配置Windows请勿关机”的提示,没过几秒后电脑自动重启,每次开机都这样无法进入系统,此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一:开机按下F8,在出现的Windows高级启动选…...
2022/11/19 21:17:12 - 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...
有不少windows10系统用户反映说碰到这样一个情况,就是电脑提示正在准备windows请勿关闭计算机,碰到这样的问题该怎么解决呢,现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法:1、2、依次…...
2022/11/19 21:17:11 - 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...
今天和大家分享一下win7系统重装了Win7旗舰版系统后,每次关机的时候桌面上都会显示一个“配置Windows Update的界面,提示请勿关闭计算机”,每次停留好几分钟才能正常关机,导致什么情况引起的呢?出现配置Windows Update…...
2022/11/19 21:17:10 - 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...
只能是等着,别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚,只能是考虑备份数据后重装系统了。解决来方案一:管理员运行cmd:net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...
2022/11/19 21:17:09 - 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?
原标题:电脑提示“配置Windows Update请勿关闭计算机”怎么办?win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢?一般的方…...
2022/11/19 21:17:08 - 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...
关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!关机提示 windows7 正在配…...
2022/11/19 21:17:05 - 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...
钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...
2022/11/19 21:17:05 - 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...
前几天班里有位学生电脑(windows 7系统)出问题了,具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面,长时间没反应,无法进入系统。这个问题原来帮其他同学也解决过,网上搜了不少资料&#x…...
2022/11/19 21:17:04 - 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...
本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法,并在最后教给你1种保护系统安全的好方法,一起来看看!电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中,添加了1个新功能在“磁…...
2022/11/19 21:17:03 - 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...
许多用户在长期不使用电脑的时候,开启电脑发现电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机。。.这要怎么办呢?下面小编就带着大家一起看看吧!如果能够正常进入系统,建议您暂时移…...
2022/11/19 21:17:02 - 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...
配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!配置windows update失败 还原更改 请勿关闭计算机&#x…...
2022/11/19 21:17:01 - 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...
不知道大家有没有遇到过这样的一个问题,就是我们的win7系统在关机的时候,总是喜欢显示“准备配置windows,请勿关机”这样的一个页面,没有什么大碍,但是如果一直等着的话就要两个小时甚至更久都关不了机,非常…...
2022/11/19 21:17:00 - 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...
当电脑出现正在准备配置windows请勿关闭计算机时,一般是您正对windows进行升级,但是这个要是长时间没有反应,我们不能再傻等下去了。可能是电脑出了别的问题了,来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...
2022/11/19 21:16:59 - 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...
我们使用电脑的过程中有时会遇到这种情况,当我们打开电脑之后,发现一直停留在一个界面:“配置Windows Update失败,还原更改请勿关闭计算机”,等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢࿰…...
2022/11/19 21:16:58 - 如何在iPhone上关闭“请勿打扰”
Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...
2022/11/19 21:16:57