PX4源码分析以及思路随笔1.docx

上传人:b****6 文档编号:12663893 上传时间:2023-06-07 格式:DOCX 页数:35 大小:51.21KB
下载 相关 举报
PX4源码分析以及思路随笔1.docx_第1页
第1页 / 共35页
PX4源码分析以及思路随笔1.docx_第2页
第2页 / 共35页
PX4源码分析以及思路随笔1.docx_第3页
第3页 / 共35页
PX4源码分析以及思路随笔1.docx_第4页
第4页 / 共35页
PX4源码分析以及思路随笔1.docx_第5页
第5页 / 共35页
PX4源码分析以及思路随笔1.docx_第6页
第6页 / 共35页
PX4源码分析以及思路随笔1.docx_第7页
第7页 / 共35页
PX4源码分析以及思路随笔1.docx_第8页
第8页 / 共35页
PX4源码分析以及思路随笔1.docx_第9页
第9页 / 共35页
PX4源码分析以及思路随笔1.docx_第10页
第10页 / 共35页
PX4源码分析以及思路随笔1.docx_第11页
第11页 / 共35页
PX4源码分析以及思路随笔1.docx_第12页
第12页 / 共35页
PX4源码分析以及思路随笔1.docx_第13页
第13页 / 共35页
PX4源码分析以及思路随笔1.docx_第14页
第14页 / 共35页
PX4源码分析以及思路随笔1.docx_第15页
第15页 / 共35页
PX4源码分析以及思路随笔1.docx_第16页
第16页 / 共35页
PX4源码分析以及思路随笔1.docx_第17页
第17页 / 共35页
PX4源码分析以及思路随笔1.docx_第18页
第18页 / 共35页
PX4源码分析以及思路随笔1.docx_第19页
第19页 / 共35页
PX4源码分析以及思路随笔1.docx_第20页
第20页 / 共35页
亲,该文档总共35页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

PX4源码分析以及思路随笔1.docx

《PX4源码分析以及思路随笔1.docx》由会员分享,可在线阅读,更多相关《PX4源码分析以及思路随笔1.docx(35页珍藏版)》请在冰点文库上搜索。

PX4源码分析以及思路随笔1.docx

PX4源码分析以及思路随笔1

PX4源码分析以及思路随笔1

PX4源码分析,以及思路随笔。

目录:

1.0环境安装

1.1rollpitchyaw

2.1loop()

3.1fastloop()

3.1.1read_AHRS()

3.1.1.1ins.update()

3.1.2rate_controller_run()

3.1.2.1_motors.set_roll()

(嵌套了rate_bf_to_motor_roll)

3.1.3motors_output()

3.1.3.1update_throttle_filter()

3.1.3.2update_battery_resistance()

3.1.3.3update_lift_max_from_batt_voltage()

3.1.3.4output_logic()

3.1.3.5output_armed_stabilizing()

 

1.0环境安装

1.首先安装px4_toolchain_installer_v14_win.exe,并配置好java环境(安装jdk,32位)。

2.安装GitHub

网站:

http:

//ardupilot.org/dev/docs/building-px4-with-make.html

若提示失败,在IE浏览器中打开网页,http变为https,不断尝试。

3.克隆程序(需要翻墙),可能多次失败。

4.从C:

\px4\toolchain\msys\1.0内的eclipse批处理文件打开eclipse。

5.按照http:

//ardupilot.org/dev/docs/editing-the-code-with-eclipse.html从第二张图开始。

注:

第二张图位置为ardupilot的位置。

返回目录

 

 

2.1loop函数:

1.Setup各种初始化,先忽略。

2.初始定义

第一个是函数名,第二个单位为赫兹为过多少时间调用一次,第三个单位为微秒,即为最大花费时间。

constAP_Scheduler:

:

TaskCopter:

:

scheduler_tasks[]={

SCHED_TASK(rc_loop,100,130),/*控制角*/

SCHED_TASK(throttle_loop,50,75),/*油门控制*/

SCHED_TASK(update_GPS,50,200),/*GPS更新*/

3.从Loop()开始。

(1)等待数据

ins.wait_for_sample(); 

我认为"ins"是"InertialSensor",也就是指惯性传感器。

voidAP_InertialSensor:

:

wait_for_sample(void)

uint32_ttimer=micros();

(2)计算最大循环时间。

perf_info_check_loop_time(timer-fast_loopTimer);检查循环时间

被PILoops使用?

G_Dt=(float)(timer-fast_loopTimer)/1000000.0f;

fast_loopTimer=timer;记录当前循环时间

mainLoop_count++;主要循环的故障检测

(3)快速循环,主要的循环,重要的一步!

因此首选需主要研究此函数!

fast_loop();

(4)任务调度

scheduler.tick();告诉调度程序,一个流程已经走完?

uint32_ttime_available=(timer+MAIN_LOOP_MICROS)-micros();

任务周期

scheduler.run(time_available);任务调度

返回目录

3.1fastloop()函数

Fastloop,最关键的循环(400hz),下面对每个函数进行工作的分析。

1.更新传感器并更新姿态的函数

read_AHRS();

2.进行角速度PID运算的函数

attitude_control.rate_controller_run();

3.直升机框架判断(HELI_FRAME)

#ifFRAME_CONFIG==HELI_FRAME

update_heli_control_dynamics();

#endif//HELI_FRAME

4.输出电机PWM值的函数

motors_output();

5.惯性导航

//InertialNav

read_inertia();

6.扩展卡尔曼滤波器

//checkifekfhasresettargetheading

check_ekf_yaw_reset();

7.更新控制模式,并计算本级控制输出下级控制输入...

//runtheattitudecontrollers

update_flight_mode();

8.扩展卡尔曼滤波器

//updatehomefromEKFifnecessary

update_home_from_EKF();

 

9.检查是否落地or追回

//checkifwe'velandedorcrashed

update_land_and_crash_detectors();

10.摄像机

#ifMOUNT==ENABLED

//cameramount'sfastupdate

camera_mount.update_fast();

#endif

11.记录传感器健康状态?

//logsensorhealth

if(should_log(MASK_LOG_ANY)){

Log_Sensor_Health();

返回目录

 

3.1.1Read_AHRS()函数

1.read_AHRS

voidCopter:

:

read_AHRS(void)

{

//PerformIMUcalculationsandgetattitudeinfo

//-----------------------------------------------

#ifHIL_MODE!

=HIL_MODE_DISABLED

//Mavlink协议支持,全传感器仿真?

模拟?

(fullsensorsimulation.)

//updatehilbeforeahrsupdate

gcs_check_input();

#endif

ahrs.update();//重要!

}

2.ahrs.update()

其中主要函数为ahrs.update(),函数为:

//DCM:

DirectionCosine Matrix,方向余弦矩阵

AP_AHRS_DCM:

:

update(void)

{

floatdelta_t;

if(_last_startup_ms==0){

_last_startup_ms=AP_HAL:

:

millis();

}

(1)更新加速度计和陀螺仪

//telltheIMUtograbsomedata

_ins.update();

//asktheIMUhowmuchtimethissensorreadingrepresents

delta_t=_ins.get_delta_time();

//iftheupdatecalltookmorethan0.2secondsthendiscardit,

//otherwisewemaymovetoofar.Thishappenswhenarmingmotors

//inArduCopter

if(delta_t>0.2f){

memset(&_ra_sum[0],0,sizeof(_ra_sum));

_ra_deltat=0;

return;

}

(2)使用陀螺仪更新四元素矩阵(做余弦矩阵的归一化)

//IntegratetheDCMmatrixusinggyroinputs

matrix_update(delta_t);

(3)标准化

//NormalizetheDCMmatrix

normalize();

(4)执行漂移修正

使用加速度计和罗盘与该次计算的四元素矩阵做差,修正出下一次陀螺仪的输出

//Performdriftcorrection

drift_correction(delta_t);

(5)检查错误值

//paranoidcheckforbadvaluesintheDCMmatrix

check_matrix();

(6)计算俯仰角,偏航角,翻转角

//Calculatepitch,roll,yawforstabilizationandnavigation

euler_angles();

(7)更新三角函数的值,包括俯仰角的余弦和翻滚角的余弦

//updatetrigvaluesincluding_cos_roll,cos_pitch

update_trig();

}

返回目录

3.1.1.1_ins.update()

更新加速度计和陀螺仪

//telltheIMUtograbsomedata

_ins.update();

函数定义:

voidAP_InertialSensor:

:

update(void):

在函数中:

_backends[i]->update();为主要操作步骤。

_backends[i]的定义为:

(是一个指针数组)

AP_InertialSensor_Backend*_backends[INS_MAX_BACKENDS];

查找_backends所指向的数据,有两个函数值得注意:

voidAP_InertialSensor:

:

_add_backend(AP_InertialSensor_Backend*backend)

VoidAP_InertialSensor:

:

detect_backends(void)

考虑在detect_backends()中进行了调用:

#elifHAL_INS_DEFAULT==HAL_INS_PX4||HAL_INS_DEFAULT==HAL_INS_VRBRAIN

_add_backend(AP_InertialSensor_PX4:

:

detect(*this));

因此得出_backends指向的是类AP_InertialSensor_PX4。

找到函数如下:

boolAP_InertialSensor_PX4:

:

update(void)

{

//getthelatestsamplefromthesensordrivers

_get_sample();

//uint8_t_num_accel_instances;

//uint8_t_num_gyro_instances;

for(uint8_tk=0;k<_num_accel_instances;k++){

update_accel(_accel_instance[k]);//加速度计

}

for(uint8_tk=0;k<_num_gyro_instances;k++){

update_gyro(_gyro_instance[k]);//陀螺仪

}

returntrue;

}

其中两个重要的函数分别为:

update_accel(_accel_instance[k])和update_gyro(_gyro_instance[k]).

首先看update_accel(_accel_instance[k]):

输入参数为_accel_instance[k]和_gyro_instance[k],定义为:

#defineINS_MAX_INSTANCES3

uint8_t_accel_instance[INS_MAX_INSTANCES];

uint8_t_gyro_instance[INS_MAX_INSTANCES];

随后看update_accel()和update_gyro()的定义:

 

voidAP_InertialSensor_Backend:

:

update_accel(uint8_tinstance)

{

hal.scheduler->suspend_timer_procs();//任务调度,推迟进程

//_imu._new_accel_data[instance]为布尔型变量,推测为观察是否可以更新

//其中_publish_accel()应该就是

if(_imu._new_accel_data[instance]){

//两个参数,其中一个是instance,另一个参考为过滤后的加速度计数据?

_publish_accel(instance,_imu._accel_filtered[instance]);

_imu._new_accel_data[instance]=false;

}

//possiblyupdatefilterfrequency设定频率?

if(_last_accel_filter_hz[instance]!

=_accel_filter_cutoff()){

_imu._accel_filter[instance].set_cutoff_frequency(_accel_raw_sample_rate(instance),_accel_filter_cutoff());

_last_accel_filter_hz[instance]=_accel_filter_cutoff();

}

//任务调度,推测为经过一个进程后重新设置

hal.scheduler->resume_timer_procs();

}

下面对于陀螺仪的控制基本没有区别:

voidAP_InertialSensor_Backend:

:

update_gyro(uint8_tinstance)

{

hal.scheduler->suspend_timer_procs();

if(_imu._new_gyro_data[instance]){

_publish_gyro(instance,_imu._gyro_filtered[instance]);

_imu._new_gyro_data[instance]=false;

}

//possiblyupdatefilterfrequency

if(_last_gyro_filter_hz[instance]!

=_gyro_filter_cutoff()){

_imu._gyro_filter[instance].set_cutoff_frequency(_gyro_raw_sample_rate(instance),_gyro_filter_cutoff());

_last_gyro_filter_hz[instance]=_gyro_filter_cutoff();

}

hal.scheduler->resume_timer_procs();

}

然后需要看一下_publish_accel()这个函数:

voidAP_InertialSensor_Backend:

:

_publish_accel(uint8_tinstance,constVector3f&accel)

{

_imu._accel[instance]=accel;

_imu._accel_healthy[instance]=true;

if(_imu._accel_raw_sample_rates[instance]<=0){

return;

}

//publishdeltavelocity

_imu._delta_velocity[instance]=_imu._delta_velocity_acc[instance];

_imu._delta_velocity_dt[instance]=_imu._delta_velocity_acc_dt[instance];

_imu._delta_velocity_valid[instance]=true;

 

if(_imu._accel_calibrator!

=NULL&&_imu._accel_calibrator[instance].get_status()==ACCEL_CAL_COLLECTING_SAMPLE){

Vector3fcal_sample=_imu._delta_velocity[instance];

//removerotation

cal_sample.rotate_inverse(_imu._board_orientation);

//removescalefactors

constVector3f&accel_scale=_imu._accel_scale[instance].get();

cal_sample.x/=accel_scale.x;

cal_sample.y/=accel_scale.y;

cal_sample.z/=accel_scale.z;

//removeoffsets

cal_sample+=_imu._accel_offset[instance].get()*_imu._delta_velocity_dt[instance];

_imu._accel_calibrator[instance].new_sample(cal_sample,_imu._delta_velocity_dt[instance]);

}

}

 

返回目录

3.1.2attitude_control.rate_controller_run()

姿态控制函数(PID函数)

attitude_control.rate_controller_run();

定义为:

voidAC_AttitudeControl:

:

rate_controller_run()

{

_motors.set_roll(rate_bf_to_motor_roll(_ang_vel_target_rads.x));

_motors.set_pitch(rate_bf_to_motor_pitch(_ang_vel_target_rads.y));

_motors.set_yaw(rate_bf_to_motor_yaw(_ang_vel_target_rads.z));

}

注:

其中,_ang_vel_target_rads.x

等三个输入参数的取得主要在voidCopter:

:

stabilize_run()内取得。

推测Angularvelocitytargetrads的含义为:

要求(期望)的角度速度

注:

rate_bf_roll_pitch_yaw():

此函数采用“车身骨架坐标系”标示翻滚、俯仰和偏航速率(度/秒)。

例:

此函数的滚动=-1000,间距=-1500,偏航=500会导致飞机向左滚动10度/秒,向前倾斜15度/秒,对于车辆的z轴旋转5度/秒。

返回目录

3.1.2.1_motors.set_roll()

1.首先分析_motors.set_roll()

定义:

voidset_roll(floatroll_in)

{_roll_in=roll_in;};

主要就是将输入的参数定义为roll_in,并传值给_roll_in。

注:

_roll_in在fastloop()内的下个函数motors_output()函数进行操作,这里我认为是个切入点!

 

set_roll()中嵌套的函数为:

rate_bf_to_motor_roll()

定义为:

floatAC_AttitudeControl:

:

rate_bf_to_motor_roll(floatrate_target_rads)

{

//从陀螺仪获取get_gyro().x,也就是当前的飞行器的翻滚角。

floatcurrent_rate_rads=_ahrs.get_gyro().x;

//翻滚角的期望与当前数值的差值

floatrate_error_rads=rate_target_rads-current_rate_rads;

//passerrortoPIDcontroller将误差传递给PID控制器,其中有微分过滤

//和将目标数据传入结构体PID。

get_rate_roll_pid().set_input_filter_d(rate_error_rads);

get_rate_roll_pid().set_desired_rate(rate_target_rads);

//进行积分

floatintegrator=get_rate_roll_pid().get_integrator();

//Ensurethatintegratorcanonlybereducediftheoutputissaturated

//确保积分只在饱和时下降

if(!

_motors.limit.roll_pitch||((integrator>0&&rate_error_rads<0)||(integrator<0&&rate_error_rads>0))){

integrator=get_rate_roll_pid().get_i();

}

//Computeoutputinrange-1~+1进行PID计算,得到控制量output。

//其中get_d()和getp中有参数_kp和_kd,没有找到是如何进行计算的!

//这里是个大问题。

floatoutput=get_rate_roll_pid().get_p()+integrator+get_rate_roll_pid().get_d();

//Constrainoutput,限制output的值,如果是非法的则变为0,如果比0小则变

//为0,大于1则为1

returnconstrain_float(output,-1.0f,1.0f);

}

剩余的

rate_bf_to_motor_pitch(_ang_vel_target_rads.y)和

rate_bf_to_motor_yaw(_ang_vel_target_rads.

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 法律文书 > 调解书

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2