关键词不能为空

当前您在: 主页 > 英语 >

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

作者:高考题库网
来源:https://www.bjmy2z.cn/gaokao
2021-02-01 18:47
tags:

-

2021年2月1日发(作者:responsible是什么意思)


PX4


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



目录:



1.0


环境安装



1.1 roll pitch yaw



2.1 loop()



3.1 fastloop()



3.1 .1



read_AHRS()



3.1.1.1




()



3.1.2



rate_controller_run()



3.1.2.1 _motors


.set_roll()



(


嵌套了


rate_bf_to_motor_roll


)


3.1.3 motors_output()



3.1.3.1



update_t hrottle_filter


()



3.1.3.2



update_b attery_resistance


()



3.1.3.3 update_lift_max_from_batt_voltage()


3.1.3.4



output_logic()


3.1.3.5 output_armed_stabilizing()














1.0


环境安装


1.


首先安装


px4_toolchain_instal ler_v14_


,并配置好


java


环境


(安装


jdk


< br>32


位)。



2.


安装


GitHub


网站:


/dev/docs/



若提示失败,在


IE


浏览器中打开网页,


http


变为


https

< br>,不断尝试。



3.


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



4.



C:px4toolchainmsys1.0


内的

< p>
eclipse


批处理文件打开


eclipse< /p>




5.


按照< /p>


/dev/docs/


从第二张图开始。



注:第二张图位置为


ardupilot


的位置。




返回目录





















1.1 ROLL YAW PITCH


/yuzhongc hun/article/details/22749521




在航空中,


pitch, yaw, roll


如图


2


所示。



pitch


是围绕


X


轴旋转,也叫做俯仰角,如图


3


所示。



yaw


是围绕


Y< /p>


轴旋转,也叫偏航角,如图


4


所示。



roll


是围绕


Z


轴旋转,也叫翻滚角,如图


5


所示。







返回目录










2.1 loop


函数:




各种初始化,先忽略。



2.


初始定义



第一个是函数名,


第二个单位为赫兹为过多少时间调用一次,


第三个


单位为微秒,即为最大花费时间。


const


AP_Scheduler


::


Task


Copter::scheduler_tasks

< br>[] = {


SCHED_TASK(rc_loop, 100, 130),


/*


控制角


*/



SCHED_TASK(throttle_loop, 50, 75),


/*


油门控制


*/



SCHED_TASK(update_GPS, 50, 200),


/* GPS


更新


*/


3.



Loop()


开始。





(1)


等待数据



_for_sample();


我认为





,也就是指惯性传感器。



void< /p>


AP_InertialSensor::wait_for_sample


(


void


)


uint32_t timer = micros();




2


)计算最大循环时间





perf_info_check_loop_time(timer -


fast_loopTimer


);


检查循环时间




PI Loops


使用??



G_Dt


= (


float


)(timer -


fast_loopTimer


) / 1000000.0f;


fast_loopTimer


= timer;


记录当前循环时间



mainLoop_count


++;


主要循环的故障检测





(3)


快速循环,

< br>主要的循环,


重要的一步!













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



fast_loop();






4


)任务 调度



scheduler


.tick();


告诉调度程序,一个流程已经走完??



uint32_t


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


任务周期



scheduler


.run(time_available);


任务调度




返回


目录



3.1 fastloop()


函数




Fastloop


,最关键的循环< /p>


(400hz)


,下面对每个函数进行工作的分

< br>析。



1.


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



read_AHRS();



2.< /p>


进行角速度


PID


运算的函数

< p>


attitude_control


.rate _controller_run();



3.


直升机框架判断




HELI_FRAME




#if


FRAME_CONFIG == HELI_FRAME


update_heli_control_dynamics();


#endif< /p>


//HELI_FRAME




4.


输出电机


PWM


值 的函数



motors_output();



5.


惯性导航



// InertialNav



read_inertia();



6.


扩展卡尔曼滤波器



// check if ekf has reset target heading



check_ekf_yaw_reset();



7.


更新控制模式


,


并计算本级控制输出下级控 制输入


...




// run the attitude controllers



update_flight_mode();



8.


扩展卡尔曼滤波器



// update home from EKF if necessary



update_home_from_EKF();




9.


检查是否落地

< br>or


追回



// check if we've landed or crashed



update_land_and_crash_detectors();



10.


摄像机



#if


MOUNT == ENABLED


// camera mount's fast update



camera_mount


.update_fast();


#endif



11.


记录传感器健康状态??



// log sensor health



if


(should_log(MASK_LOG_ANY)) {


Log_Sensor_Health();




返回目录























3.1.1 Read_AHRS()


函数



1.


read_AHRS


< p>
void


Copter::read_AHRS


(


void


)


{


// Perform IMU calculations and get attitude info



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



#if


HIL_MODE != HIL_MODE_DISABLED


//Mavlink


协议支持



,全传感器仿真??模拟?(


full sensor simulation.




// update hil before ahrs update



gcs_check_input();


#endif



ahrs


.update();


//


重要!



}


2.


ahrs


.update()



其中主要函数为


ahrs

< p>
.update()


,函数为:



//DCM



DirectionCosine Matrix


,方向余弦矩阵



AP_ AHRS_DCM::update


(


void


)


{


float


delta_t;



if


(


_last_startup_ms


== 0) {


_last_startup_ms


= AP_HAL::millis();


}


(1)


更新加速度计和陀螺仪



// tell the IMU to grab some data



_ins


.update();



// ask the IMU how much time this sensor reading represents



delta_t =


_ins


.get_delta_time();


// if the update call took more than 0.2 seconds then discard it,



// otherwise we may move too far. This happens when arming motors



// in ArduCopter



if


(delta_t > 0.2f) {


memset(&


_ra_sum


[0], 0,

< p>
sizeof


(


_ra_sum

< br>));


_ra_deltat


= 0;


return


;


}


(2)


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

< p>


// Integrate the DCM matrix using gyro inputs



matrix_update(delta_t);


(3)


标准化



// Normalize the DCM matrix



normalize();


(4)


执行漂移修正



使用加速度计和罗盘与该次计算的四元素矩阵做差,


修正出下一


次陀螺仪的输出



// Perform drift correction



drift_correction(delta_t);


(5)


检查错误值



// paranoid check for bad values in the DCM matrix



check_matrix();


(6)


计算俯仰角,偏航角,翻转角



// Calculate pitch, roll, yaw for stabilization and navigation



euler_angles();


(7)


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



// update trig values including _cos_roll, cos_pitch



update_trig();


}



返回目录




3.1.1.1 _ins


.update()



更新加速度计和陀螺仪



// tell the IMU to grab some data



_ins


.update();


函数 定义:


void


AP_InertialSensor::up date


(


void


)





在函数中:

< p>
_backends


[i]->update();


为主要操作步骤。



_backend s


[i]


的定义为:


(


是一个指针数组


)


AP_InertialSensor_Backend


*< /p>


_backends


[INS_MAX_BACKENDS];


查找


_backends


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



void


A P_InertialSensor::_add_backend


(AP_Inert ialSensor_Backend


*backend)


Void


AP_InertialSensor::detect_backends< /p>


(


void


)


考虑在


detect_backends()


中进行了调用:< /p>



#elif


HAL_INS_DEFAULT == HAL_INS_PX4 || HAL_INS_DEFAULT ==


HAL_INS_VRBRAIN


_add_ backend(AP_InertialSensor_PX4::detect(*


this


));



因此得出


_backends


指向的是类


AP_Ine rtialSensor_PX4


。找到函数如下:



bool


AP_InertialSensor_PX4::

< p>
update


(


void


)


{


// get the latest sample from the sensor drivers



_get_sample();


// uint8_t _num_accel_instances;


// uint8_t _num_gyro_instances;


for


(uint8_t k=0; k<_num_accel_instances; k++) {


update_accel(_accel_instance[k]); //


加速度计



}



for


(uint8_t k=0; k<_num_gyro_instances; k++) {


update_gyro(_gyro_instance[k]); //


陀螺仪



}



returntrue


;


}


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


< /p>


update_accel(_accel_instance[k])

< br>和


update_gyro(_gyro_instance[k]).



首先看


update_accel( _accel_instance[k])




输入参数为


_accel_instance[k]



_gyro_instance[k]


,定义为:



#define


INS_MAX_INSTANCES 3


uint8_t _accel_instance[INS_MAX_INSTANCES];


uint8_t _gyro_instance[INS_MAX_INSTANCES];



随后看


update_accel()



update_gyro()


的定义:












void


AP_InertialS ensor_Backend::update_accel


(


uint8_t


instance)


{


hal.


scheduler


->suspend_timer_procs();


//


任务 调度,推迟进程



//_imu._new_acce l_data[instance]


为布尔型变量,推测为观察是否可以更新

< p>


//


其中


_p ublish_accel()


应该就是



if


(


_imu

.


_new_accel_data


[instance] ) {


//


两个参数,其中一个是

< br>instance


,另一个参考为过滤后的加速度计数据??


_publish_accel(instance,


_imu


.


_accel_filtered


[instance]);


_imu


.


_new_accel_data


[instance] =


false


;


}



// possibly update filter frequency


设定频率?



if


(


_last_accel_f ilter_hz


[instance] != _accel_filter_cutoff()) {


_imu

.


_accel_filter


[instance].s et_cutoff_frequency(_accel_raw_sample_r


ate(instance), _accel_filter_cutoff());


_last_accel_filter_hz


[instance] = _accel_filter_cutoff();


}


//


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



hal.


scheduler


->resume_timer_procs();


}



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



void


AP_InertialSensor_Backend::update_ gyro


(


uint8_t


instance)


{


hal.


scheduler


->suspend_timer_procs() ;



if


(


_imu


.


_new_gyro_data

< br>[instance]) {


_publish_gyro(instance,


_imu


.


_gyro_filtered


[instance]);


_imu


.


_new_gyro_da ta


[instance] =


false


;


}



// possibly update filter frequency



if


(


_last_gyro_filter_hz


[instance] != _gyro_filter_cutoff()) {


_imu


.


_gyro_filter


[instance]. set_cutoff_frequency(_gyro_raw_sample_rat

e(instance), _gyro_filter_cutoff());


_last_gyro_filter_hz


[instance] = _gyro_filter_cutoff();


}



hal.


schedule r


->resume_timer_procs();


}



然后需要看一下


_publish_ accel()


这个函数


:



void


AP_InertialSensor_Backend:: _publish_accel


(


uint8_t


instance,


const


Vector3f&accel)


{


_imu


.


_accel


[instance] = accel;


_ imu


.


_accel_healthy


[instance] =


true


;



if


(


_ imu


.


_accel_raw_sample_rates< /p>


[instance] <= 0) {


return


;


}



// publish delta velocity



_imu


.


_delta_velocity


[instance] =


_imu


.


_delta_velocity _acc


[instance];


_imu

< br>.


_delta_velocity_dt


[insta nce] =


_imu


.


_delt a_velocity_acc_dt


[instance];


_imu


.


_delta_velocity_valid< /p>


[instance] =


true


;




if


(


_imu


.


_accel_calib rator


!=


NULL&&


_i mu


.


_accel_calibrator

< br>[instance].get_status() ==


ACCEL_CAL_COLLECTING_SAMPLE


) {


Vector3f cal_sample =


_imu


.


_delta_velocity


[ instance];



//remove rotation



cal__invers e(


_imu


.


_board_ori entation


);



// remove scale factors



const


Vector3f&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;



//remove offsets



cal_sample +=


_imu


.

_accel_offset


[instance].get() *

< p>
_imu


.


_delta_velocity_d t


[instance]



_i mu


.


_accel_calibrator

< br>[instance].new_sample(cal_sample,


_i mu


.


_delta_velocity_dt


[instance]);


}


}





返回目录



3.1.2 attitude_control


.rate_controller_run()



姿态控制函数(


PID


函数)



attitude_control


.rate_controller_run();


定义为:



void

< br>AC_AttitudeControl::rate_controller_run

< br>()


{


_motors


.s et_roll(rate_bf_to_motor_roll(


_ang_vel_ target_rads


.


x


));


_motors


.set_pitch(rate_bf_to _motor_pitch(


_ang_vel_target_rads


.


y


));


_motor s


.set_yaw(rate_bf_to_motor_yaw(

< br>_ang_vel_target_rads


.


z


));


}


注:其中,


_ang_vel_target_rads.x


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


void Copter::stabilize_run()


内取得。



推测


Angularvelocity target rad s


的含义为:要求


(


期望


)


的角度速度




注:


rate_bf_roll_pitch_yaw():


< br>此函数采用“车身骨架坐标系”标示翻滚、俯仰和偏航速率


(


/



)





例:此函数的滚动


= -1000,


间距


= -1500,


偏航


= 500


会导致飞 机向左滚动


10



/

< br>秒


,


向前倾斜


15



/



,

< br>对于车辆的


z


轴旋转


5



/


秒。




返回目录




3.1.2.1 _motors


.set_roll()



1.


首先分析


_motor s


.set_roll()


定义:



void


set_roll


(


float


roll_in)


{


_roll_in


= roll_in; };

< p>
主要就是将输入的参数定义为


roll_in


,并 传值给


_roll_in





_roll_in



fastloop()








motors_ output()


函数进行操作,这里我认为是个切入点!






set _roll()


中嵌套的函数为:


rate_bf_to_mo tor_roll()


定义为:



f loat


AC_AttitudeControl::rate_bf_to_moto r_roll


(


float



rate_target_rads)


{


//


从陀螺仪获取


get_g yro().x


,也就是当前的飞行器的翻滚角。



float


current_rate_rads =


_ahrs


.get_gyro().


x< /p>


;


//


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



float


rate_error_rads = rate_target_rads - current_rate_rads;


// pass error to PID controller


将误差传递给


PID


控制器


,


其中有微分过滤



//


和将目标数据传入结构体


PID



get_rate_roll_pid().set_input_fi lter_d(rate_error_rads);


get_rate_r oll_pid().set_desired_rate(rate_target_rads);


//


进行积分



float


integrator = get_rate_roll_pid().get_integrator();


//


Ensure


that


integrator


can


only


be


reduced


if


the


output


is


saturated


//


确保积分只在饱和时下降



if


(!


_motors

< p>
.


limit


.


roll _pitch


|| ((integrator > 0 && rate_error_rads <


0) || (integrator < 0 && rate_error_rads > 0))) {


integrator = get_rate_roll_pid().get_i();


}


// Compute output in range -1 ~ +1


进行


PID


计算,得到控制量


output




//


其中


get_d()



getp


中有参数


_kp



_kd


,没有找到是如何进行计算的 !



//


这里是个大问题。



float


output = get_rate_roll_pid().get_p() + integrator +


get_rate_roll_pid().get_d();


//


Constrain


output



限制


output


的值,如果是非法的则变为


0


,如果比


0


小则变



//



0,


大于


1


则为


1


return


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


}


剩余的



rate_bf_to_mo tor_pitch(


_ang_vel_target_rads

.


y


)




rate_bf_to_motor_yaw(


_ang_ve l_target_rads


.


z


)< /p>


与第一个没有差别



在这三个函数中,我们分别获得了三个参数,



_roll_in



_pitch_in



_yaw_in



取值范 围在


-1



1



应该会应用在


fastloop()


中的下个函数


motors_output()




返回目录

















-


-


-


-


-


-


-


-



本文更新与2021-02-01 18:47,由作者提供,不代表本网站立场,转载请注明出处:https://www.bjmy2z.cn/gaokao/594549.html

PX4源码分析以及思路随笔1的相关文章

  • 爱心与尊严的高中作文题库

    1.关于爱心和尊严的作文八百字 我们不必怀疑富翁的捐助,毕竟普施爱心,善莫大焉,它是一 种美;我们也不必指责苛求受捐者的冷漠的拒绝,因为人总是有尊 严的,这也是一种美。

    小学作文
  • 爱心与尊严高中作文题库

    1.关于爱心和尊严的作文八百字 我们不必怀疑富翁的捐助,毕竟普施爱心,善莫大焉,它是一 种美;我们也不必指责苛求受捐者的冷漠的拒绝,因为人总是有尊 严的,这也是一种美。

    小学作文
  • 爱心与尊重的作文题库

    1.作文关爱与尊重议论文 如果说没有爱就没有教育的话,那么离开了尊重同样也谈不上教育。 因为每一位孩子都渴望得到他人的尊重,尤其是教师的尊重。可是在现实生活中,不时会有

    小学作文
  • 爱心责任100字作文题库

    1.有关爱心,坚持,责任的作文题库各三个 一则150字左右 (要事例) “胜不骄,败不馁”这句话我常听外婆说起。 这句名言的意思是说胜利了抄不骄傲,失败了不气馁。我真正体会到它

    小学作文
  • 爱心责任心的作文题库

    1.有关爱心,坚持,责任的作文题库各三个 一则150字左右 (要事例) “胜不骄,败不馁”这句话我常听外婆说起。 这句名言的意思是说胜利了抄不骄傲,失败了不气馁。我真正体会到它

    小学作文
  • 爱心责任作文题库

    1.有关爱心,坚持,责任的作文题库各三个 一则150字左右 (要事例) “胜不骄,败不馁”这句话我常听外婆说起。 这句名言的意思是说胜利了抄不骄傲,失败了不气馁。我真正体会到它

    小学作文