匿名无人机代码FlightCtrl简单分析

这个flightCtrl文件,是真的很长又很难。。。各种标志位啊,判断啊,开关啊,逻辑判断啊什么的,趁通宵把代码梳理一遍。

这个文件里的函数虽不算最多,但引用的头文件相当多,也就是说这个东西跟整个系统各个部分都有关系,难度也就最大。。。不过仔细看应该还是能看懂的,就是费点时间。

1、pid初始化:

void All_PID_Init(void)
{

	Att_1level_PID_Init();

	Att_2level_PID_Init();

	Alt_1level_PID_Init();	

	Alt_2level_PID_Init();

	Loc_1level_PID_Init();
	
}

正好一共五个环。。。

2、控制参数改变任务:

void ctrl_parameter_change_task()
{

	if(0)
	{
		Set_Att_2level_Ki(0);
		
	}
	else
	{
		if(flag.auto_take_off_land ==AUTO_TAKE_OFF)
		{

			Set_Att_1level_Ki(2);
		}
		else
		{

			Set_Att_1level_Ki(1);
		}
		
		Set_Att_2level_Ki(1);
	}
}

如果这个东西是这个,flag.auto_take_off_land ==AUTO_TAKE_OFF,那么就这样,否则就那样。。。仍然是调参,不知怎么用。

3、有关一键起飞

    static u16 one_key_taof_start;
               //主要功能为延时
    void one_key_take_off_task(u16 dt_ms)
    {
    	if(one_key_taof_start != 0)
    	{
    		one_key_taof_start += dt_ms;
    		
    		
    		if(one_key_taof_start > 1400 && flag.motor_preparation == 1)
    		{
    			one_key_taof_start = 0;
    				if(flag.auto_take_off_land == AUTO_TAKE_OFF_NULL)
    				{
					flag.auto_take_off_land = AUTO_TAKE_OFF;
					//解锁、起飞
    
    					flag.taking_off = 1;
    				}
    			
    		}
    	}
    	//reset
    	if(flag.unlock_sta == 0)
    	{
    		one_key_taof_start = 0;
    	}
    
    }
  //一键起飞
    void one_key_take_off()
    {
    	if(flag.unlock_err == 0)
    	{	
    		if(flag.auto_take_off_land == AUTO_TAKE_OFF_NULL && one_key_taof_start == 0)
    		{
    			one_key_taof_start = 1;
    			flag.unlock_cmd = 1;
    		}
    	}
    }

有关一键起飞的内容,具体来讲是这样的:
1、在高度控制环void Alt_2level_Ctrl(float dT_s)中,
会自动调用自动起飞降落任务:void Auto_Take_Off_Land_Task(u8 dT_ms)

2、这个任务又会调用一键起飞任务:one_key_take_off_task(dT_ms),同时如果此时flag.unlock_sta置位、flag.taking_off置位、flag.auto_take_off_land == AUTO_TAKE_OFF_NULL状态为起飞无效,那么就把auto_take_off_land设置为起飞,再后面会判断这个auto_take_off_land,如果是起飞,就赋值一个速度让它起飞,并且定时退出。
3、那么什么时候这些标志位会符合条件呢?就在它调用的one_key_take_off_task(dT_ms)里。在这个任务里,如果one_key_taof_start为1,那么就延时一段时间,然后使得
flag.taking_off = 1;flag.auto_take_off_land = AUTO_TAKE_OFF;
也就满足了刚刚的条件,也就可以起飞。
4、又是什么时候one_key_taof_start为1?就由我们来控制了。我们调用void one_key_take_off(),就可以了。。。

确实有点复杂。。。

4、降落判别:

void land_discriminat(s16 dT_ms)

也就是说判断什么时候该降落的函数。

if((fs.speed_set_h_norm[Z] < 0.1f) || flag.auto_take_off_land == AUTO_LAND)
{
	if(ld_delay_cnt>0)
	{
		ld_delay_cnt -= dT_ms;
	}
}
else
{
	ld_delay_cnt = 200;
}

如果油门值持续小于0.1,或者启动了自动降落,那么就计数。

if(ld_delay_cnt <= 0 && (flag.thr_low || flag.auto_take_off_land == AUTO_LAND) )
{
	
	if(mc.ct_val_thr<250 && flag.unlock_sta == 1 && flag.locking != 2)//ABS(wz_spe_f1.out <20 ) 
	{
		if(landing_cnt<1500)
		{
			landing_cnt += dT_ms;
		}
		else
		{

			flying_cnt = 0;
			flag.taking_off = 0;
			
				landing_cnt =0;	
				flag.unlock_cmd =0;				

			flag.flying = 0;

		}
	}
	else
	{
		landing_cnt = 0;
	}

}

计数完成后,且油门为低或者启动了自动降落,那么如果此时状态为:油门小于250,且解锁了,且并未在上锁的过程中,那么这个状态持续1.5s后:
flag.taking_off = 0;起飞标志位清零
flag.unlock_cmd =0; 锁定命令有效

5、void Flight_State_Task(u8 dT_ms,s16 *CH_N)
这个会在主函数里轮询。

    s16 thr_deadzone;
    static float max_speed_lim,vel_z_tmp[2];
        //设置油门摇杆量
    thr_deadzone = (flag.wifi_ch_en != 0) ? 0 : 50;
    fs.speed_set_h_norm[Z] = my_deadzone(CH_N[CH_THR],0,thr_deadzone) *0.0023f;
    fs.speed_set_h_norm_lpf[Z] += 0.5f *(fs.speed_set_h_norm[Z] - fs.speed_set_h_norm_lpf[Z]);

得到代表遥控油门的数据。

if(flag.unlock_sta)
{	
	if(fs.speed_set_h_norm[Z]>0.01f && flag.motor_preparation == 1) // 0-1
	{
		flag.taking_off = 1;
	}	
}		

如果解锁了,那么有摇杆量、且电机准备好了的时候,taking_off,表示起飞了。

if(flag.taking_off)
{
		
	if(flying_cnt<1000)//800ms
	{
		flying_cnt += dT_ms;
	}
	else
	{
		flag.flying = 1;  
	}
	
	if(fs.speed_set_h_norm[Z]>0)
	{	
		vel_z_tmp[0] = (fs.speed_set_h_norm_lpf[Z] *MAX_Z_SPEED_UP);
	}
	else
	{
		vel_z_tmp[0] = (fs.speed_set_h_norm_lpf[Z] *MAX_Z_SPEED_DW);
	}

	vel_z_tmp[1] = vel_z_tmp[0] + program_ctrl.vel_cmps_h[Z] + pc_user.vel_cmps_set_z;
	//
	vel_z_tmp[1] = LIMIT(vel_z_tmp[1],fc_stv.vel_limit_z_n,fc_stv.vel_limit_z_p);
	//
	fs.speed_set_h[Z] += LIMIT((vel_z_tmp[1] - fs.speed_set_h[Z]),-0.8f,0.8f);//ÏÞÖÆÔöÁ¿·ù¶È
}

如果已经起飞了,那么等待一秒,并将flying置一,表示已经在飞了。
如果油门值大于0,就是上升,设置上升速度,否则设置下降速度。
总的速度相加,赋值给vel_z_tmp[1],并限幅。
最后赋值给fs.speed_set_h[Z],作为系统给的最终的z轴速度。
如果没有起飞,fs.speed_set_h[Z]直接0.

fs.speed_set_h_norm[X] = (my_deadzone(+CH_N[CH_PIT],0,50) *0.0022f);
fs.speed_set_h_norm[Y] = (my_deadzone(-CH_N[CH_ROL],0,50) *0.0022f);
	
LPF_1_(3.0f,dT_ms*1e-3f,fs.speed_set_h_norm[X],fs.speed_set_h_norm_lpf[X]);
LPF_1_(3.0f,dT_ms*1e-3f,fs.speed_set_h_norm[Y],fs.speed_set_h_norm_lpf[Y]);

max_speed_lim = MAX_SPEED;

取遥控器的XY速度,赋值给这些东西、滤波。。

speed_set_tmp[X] = fc_stv.vel_limit_xy *fs.speed_set_h_norm_lpf[X] + program_ctrl.vel_cmps_h[X] + pc_user.vel_cmps_set_h[X];
speed_set_tmp[Y] = fc_stv.vel_limit_xy *fs.speed_set_h_norm_lpf[Y] + program_ctrl.vel_cmps_h[Y] + pc_user.vel_cmps_set_h[Y];

length_limit(&speed_set_tmp[X],&speed_set_tmp[Y],fc_stv.vel_limit_xy,fs.speed_set_h_cms);

fs.speed_set_h[X] = fs.speed_set_h_cms[X];
fs.speed_set_h[Y] = fs.speed_set_h_cms[Y];	

同样,XY的速度等于这些相加,最后赋值给fs.这个东西。。

land_discriminat(dT_ms);

if(rolling_flag.rolling_step == ROLL_END)
{
	if(imu_data.z_vec[Z]<0.25f)
	{
	flag.unlock_cmd = 0;
	}

}	

是否降落的检测,然后是倾斜过大上锁。

if(sensor.gyr_CALIBRATE != 0 || sensor.acc_CALIBRATE != 0 ||sensor.acc_z_auto_CALIBRATE)
{
	imu_state.G_reset = 1;
}

if(imu_state.G_reset == 1)
{
	flag.sensor_imu_ok = 0;
	LED_STA.rst_imu = 1;
	WCZ_Data_Reset(); 
}
else if(imu_state.G_reset == 0)
{	
	if(flag.sensor_imu_ok == 0)
	{
		flag.sensor_imu_ok = 1;
		LED_STA.rst_imu = 0;
		ANO_DT_SendString("IMU OK!");
	}
}

检测imu,并改变标志位sensor_imu_ok

	if(flag.unlock_sta == 0)
	{
		flag.flying = 0;
		landing_cnt = 0;
		flag.taking_off = 0;
		flying_cnt = 0;
		
		
		flag.rc_loss_back_home = 0;
		
		if(flag.taking_off == 0)
		{
		}
	}

如果解锁位位0,也就锁定状态,那么flag.taking_off = 0;flag.flying = 0;
flag.rc_loss_back_home = 0;(???)

没了,大体来讲,这个函数就是判断状态、改变标志位、赋值速度等等。。。

6、void Swtich_State_Task(u8 dT_ms)
开关状态任务。
大致的意思就是根据各个模块的状态来看是否打开开关。
1、气压计默认打开
2、光流:需要高度、光的质量达到要求、并且飞机处于LOC_HOLD模式,光流开关才会打开。激光模块一直是关的(?)
3、uwb不知道啥东西,但也只在定位模式才会有用
4、openmv也只会在定位的时打开。。。(这里有点疑惑,追踪和循迹都不是定位模式把,但需要用到openmv啊)

7、void Flight_Mode_Set(u8 dT_ms):飞行模式设置
也会被轮询

if(CH_N[AUX1] <-100 && CH_N[AUX1]>-200)
{
	flag.chn_failsafe = 1;
}

接收机失控,此时需要降落保护

else
{
	flag.chn_failsafe = 0;
	
	if(CH_N[AUX1]<-300)
	{
		flag.flight_mode = ATT_STAB;
	}
	else if(CH_N[AUX1]<200)
	{
		flag.flight_mode = LOC_HOLD;
	}
	else
	{
		flag.flight_mode = RETURN_HOME;
	}
}

可以看出CH_N[AUX1]是更改模式的,可以失控、自稳、定位、回家

if(flight_mode_old != flag.flight_mode) 
{
	flight_mode_old = flag.flight_mode;
	
	flag.rc_loss_back_home = 0;

}

如果状态改变,就把新值保存。flag.rc_loss_back_home = 0;是降落回家信号,但似乎没有用上过,因为要配合gps才能回家。。。

大概看完了。。。挺琐碎的,就当做个记录,最后跟工程一起总结把。。。

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值