無人機高度控制
這個第一次看就完全沒看懂,現在再看還是沒看懂orz,而且定高還是重要的功能和考點,詳細分析一下程序吧。。。。
首先是表示高度信息的結構體:
//數據結構聲明
typedef struct
{
float Z_Speed;
float Z_Acc;
float Z_Postion;
float Alt;
uint16_t Thr;
}HeightInfo_t;
//Extern引用
extern HeightInfo_t HeightInfo;
分別是速度、加速度和位置(也就是高度?),下面兩個是高度(?)和油門(throttle)
然后就是代碼了,長的一批,頭文件省略了:
#define THROTTLE_BASE 600
//Extern引用
extern SPL06Manager_t g_SPL06Manager;
spl06的信息結構體,定義是這樣的,數據有點多:
typedef struct {
SPL06Param_t0 Param;
uint8_t u8Chip_id;
long i32RawPressure;
long i32RawTemperature;
long i32KP;
long i32KT;long fGround_Alt;
long fALT; //height above sea level
float fRelative_Alt;float fTemperature;
float fPressure;
float fLast_Pressure;float fOffset;
bool Check; }SPL06Manager_t;
//私有函數區
//私有變量區
HeightInfo_t HeightInfo;
float dt2 = 0;
bool Acc_Enable_Flag = false;
#include "gcs.h"
#define MAX_EXP_WZ_VEL_UP 200
#define MAX_EXP_WZ_VEL_DW 150
#define MAX_EXP_WZ_ACC 500
exp表示期望值,所以上面三個宏定義意思大概是:最大的期望上升速度,最大的期望下降速度,以及最大的期望加速度。WZ大概是指Z軸方向?不確定
//wz_ctrl struct
static float exp_vel_transition[4];
static float exp_vel_d;
應該是期望速度和期望速度增量,都是靜態變量。
static float exp_acc;
static float fb_acc;
static float exp_vel;
static float fb_vel;
float exp_hei;
static float fb_hei;
期望加速度、反饋加速度、期望速度、反饋速度、期望高度、反饋高度?
不知道反饋在這里指啥。。。
//pid struct
static float hei_err,vel_err,acc_err,acc_err_i,acc_out,wz_out;
#define H_KP 1.5f
#define V_KP 5.0f
#define V_KD 0.05f
#define A_KP 0.4f
#define A_KI 0.6f
上面這些與pid有關,定義了靜態變量:高度偏差、速度偏差、加速度偏差、加速度偏差i(?不知道是啥)、加速度輸出(?)、wz輸出(?)。。。一半都看不懂。。。
宏定義的話可能比較好理解,是高度控制的p系數、速度控制的PD系數、加速度控制的PI系數。
//fc的意思是飛控
//extern uint8_t fc_state
uint8_t fc_state_take_off = 0;
void ALT_Ctrl(float dT_s)
{
//==input calculate
//fb = feedback 更新反饋信息
fb_vel = HeightInfo.Z_Speed;
fb_hei = HeightInfo.Z_Postion;
fb_acc = HeightInfo.Z_Acc;
反饋的高度、速度、加速度信息就是當前狀態結構體中的三個值。
//期望速度由遙控器數據轉換而來
exp_vel_transition[0] = (Remote.thr - 1500)*0.0008f;
//死區控制SSZQxaQxzz
if(exp_vel_transition[0]<0.3f && exp_vel_transition[0]>-0.3f)
{
exp_vel_transition[0] = 0;
}
//超過死區范圍,則計算期望速度
if(exp_vel_transition[0] > 0)
{
exp_vel_transition[1] = exp_vel_transition[0] * MAX_EXP_WZ_VEL_UP;
}
else
{
exp_vel_transition[1] = exp_vel_transition[0] * MAX_EXP_WZ_VEL_DW;
}
這個tran[4]數組作用是。。。沒看懂,大膽猜測,應該是速度的期望值需要逐步變換求得?
其中tran[0]直接表示油門轉換來的數據,然后乘以一個最大期望速度,得到tran[1],猜想應該0代表了比例,1代表有意義的期望值?
//計算最大的期望速度增量
float tmp = MAX_EXP_WZ_ACC * dT_s;
//計算期望速度增量
exp_vel_d = (exp_vel_transition[1] - exp_vel_transition[2]);
//期望速度增量限幅
if(exp_vel_d > tmp)
{
exp_vel_d = tmp;
}
else if(exp_vel_d < -tmp)
{
exp_vel_d = -tmp;
}
可以看出tran[1]-tran[2]是期望速度增量,而tran[1]是期望速度,那么tran[2]也是期望速度,但是是上一次的。
//期望速度為疊加速度增量,相當于加速度積分
exp_vel_transition[2] += exp_vel_d;
//期望速度LPF
exp_vel_transition[3] += 0.2f *(exp_vel_transition[2] - exp_vel_transition[3]);
嗯,tran[2]就是上次的期望速度,加上期望速度增量,就是本次的期望速度。
然后經過濾波得到tran[3],tran[3]是最后得到的期望速度。
//==exp_val state
//
if(g_UAVinfo.UAV_Mode >= Altitude_Hold && fc_state_take_off != 0 )
{
//最終的期望速度為exp_vel
exp_vel = exp_vel_transition[3];
//期望高度為期望速度的積分
exp_hei += exp_vel * dT_s;
//期望高度限幅
if(exp_hei > fb_hei+150)
{
exp_hei = fb_hei+150;
}
else if(exp_hei < fb_hei-150)
{
exp_hei = fb_hei-150;
}
}
else
{
exp_vel = 0;
exp_hei = fb_hei;
}
然后得到的期望速度tran[3],乘以單位時間,加在當前高度上,就得到了期望高度,然后限幅,就得到了最終的期望高度。
//==ctrl
//高度誤差 = 期望高度誤差 - 反饋誤差
hei_err = (exp_hei - fb_hei);
//速度誤差 = (Kp * 高度誤差 + 期望速度) - (反饋速度 + 反饋加速度 * kd)
//為何此處速度誤差不為:vel_err = exp_vel - fb_vel;
//PD控制,快速收斂到期望速度
vel_err = ((H_KP * hei_err + exp_vel) - (fb_vel + V_KD *fb_acc));
高度偏差等于期望高度—反饋高度
速度偏差等于這個公式。。。不知道啥意思,為何不是這個我也想問。。。
反正先這樣了。。。
//期望加速度 = Kp * 速度誤差,純P控制,快速收斂到期望加速度
exp_acc = (V_KP * vel_err);
//加速度誤差 = 期望加速度 - 反饋加速度
//對加速度進行PI控制
acc_err = exp_acc - fb_acc;
acc_err_i += A_KI * acc_err * dT_s;
acc_err_i = (acc_err_i > 600)?600:((acc_err_i<0)?0:acc_err_i);
//最終輸出為 Kp * 加速度期望值 + 加速度積分值(PI控制)
acc_out = A_KP * exp_acc;
wz_out = acc_out + acc_err_i;
//輸出限幅
wz_out = (wz_out > 1000)?1000:((wz_out < 0)?0:wz_out);
HeightInfo.Thr = (uint16_t)wz_out;
反正不管咋樣得到了油門的值。。。。
//unlock state
//如果飛機未解鎖,則將加速度的積分量置零,高度期望值與反饋值相同
if(g_FMUflg.unlock == 0)
{
acc_err_i = 0;
exp_hei = fb_hei;
fc_state_take_off = 0;
for(int i = 0;i<4;i++)
{
exp_vel_transition[i] = 0;
}
}
else
{
if(g_UAVinfo.UAV_Mode >= Altitude_Hold)
{
//超過中位,狀態切換為起飛
if(exp_vel_transition[0]>0)
{
fc_state_take_off = 1;
}
}
else//g_UAVinfo.UAV_Mode < Altitude_Hold
{
fc_state_take_off = 1;
}
}
}
看不懂,我服了。。。這玩意就先到這吧,定高這部分查了查資料也沒結果,好像新的無人機有啥光流傳感,接下來看看那個吧。。
智能推薦
Dronekit代碼學習(三)控制無人機前后左右升降俯仰
Dronekit代碼學習(三)控制無人機前后左右升降俯仰 控制無人機前后左右升降俯仰 代碼如下: 起飛5m后,右5m,前方5m,升2m,返航,關閉連接 升降是反的...
十、鍵盤控制無人機 · 下(multirotor_keyboard_control.py解讀)
筆記來源于開源項目:基于PX4和ROS的無人機仿真平臺 來源于開源項目:GAAS 目錄 一、解讀啟動通信的multirotor_keyboard_control.py腳本 1、庫函數以及消息 2、變量及其初始值 3、主函數外的getKey()和print_msg()函數 4、main主函數 (1)、初始值的設立 (2)、while循環監聽鍵盤的輸入做出反應 二、打開程序,查看節點話題關系圖 &nb...
基于模型預測控制MPC的無人機軌跡跟蹤
模型預測控制MPC 算法主要思想是用優化的方法解決控制和規劃問題。 MPC主要分為三部分 建模:系統建模和問題建模 預測:參數空間 狀態空間 輸入空間 控制:選擇最好的策略 算法過程 系統建模 問題建模 優化 控制 基本的MPC過程用MATLAB代碼實現 主函數 hw8.m getMPC函數 預測矩陣函數 getPrectioninMAtrix.m 結果...
freemarker + ItextRender 根據模板生成PDF文件
1. 制作模板 2. 獲取模板,并將所獲取的數據加載生成html文件 2. 生成PDF文件 其中由兩個地方需要注意,都是關于獲取文件路徑的問題,由于項目部署的時候是打包成jar包形式,所以在開發過程中時直接安照傳統的獲取方法沒有一點文件,但是當打包后部署,總是出錯。于是參考網上文章,先將文件讀出來到項目的臨時目錄下,然后再按正常方式加載該臨時文件; 還有一個問題至今沒有解決,就是關于生成PDF文件...
猜你喜歡
電腦空間不夠了?教你一個小秒招快速清理 Docker 占用的磁盤空間!
Docker 很占用空間,每當我們運行容器、拉取鏡像、部署應用、構建自己的鏡像時,我們的磁盤空間會被大量占用。 如果你也被這個問題所困擾,咱們就一起看一下 Docker 是如何使用磁盤空間的,以及如何回收。 docker 占用的空間可以通過下面的命令查看: TYPE 列出了docker 使用磁盤的 4 種類型: Images:所有鏡像占用的空間,包括拉取下來的鏡像,和本地構建的。 Con...
requests實現全自動PPT模板
http://www.1ppt.com/moban/ 可以免費的下載PPT模板,當然如果要人工一個個下,還是挺麻煩的,我們可以利用requests輕松下載 訪問這個主頁,我們可以看到下面的樣式 點每一個PPT模板的圖片,我們可以進入到詳細的信息頁面,翻到下面,我們可以看到對應的下載地址 點擊這個下載的按鈕,我們便可以下載對應的PPT壓縮包 那我們就開始做吧 首先,查看網頁的源代碼,我們可以看到每一...
Linux C系統編程-線程互斥鎖(四)
互斥鎖 互斥鎖也是屬于線程之間處理同步互斥方式,有上鎖/解鎖兩種狀態。 互斥鎖函數接口 1)初始化互斥鎖 pthread_mutex_init() man 3 pthread_mutex_init (找不到的情況下首先 sudo apt-get install glibc-doc sudo apt-get install manpages-posix-dev) 動態初始化 int pthread_...
統計學習方法 - 樸素貝葉斯
引入問題:一機器在良好狀態生產合格產品幾率是 90%,在故障狀態生產合格產品幾率是 30%,機器良好的概率是 75%。若一日第一件產品是合格品,那么此日機器良好的概率是多少。 貝葉斯模型 生成模型與判別模型 判別模型,即要判斷這個東西到底是哪一類,也就是要求y,那就用給定的x去預測。 生成模型,是要生成一個模型,那就是誰根據什么生成了模型,誰就是類別y,根據的內容就是x 以上述例子,判斷一個生產出...