多旋翼无人机

    返回首页    发表留言
本文作者:李德强
          第二节 状态机切换
 
 

        在本节我们来学习Commander中的3种状态切换过程,其中包括无人机的解锁状态处理、主状态处理和导航状态处理。这3种状态是无人机中非常重要的状态,直接影响飞机的控制导航逻辑和控制逻辑,进而影响飞机的实际飞行效果。下面我们就来分别对这3种飞行状态的处理过程进行分析:

一、arming_state解锁/锁定状态

        解锁状态在PX4飞控程序中的定义名称为Arming state表示飞机当前的解锁和锁定状态,它被定义成vehicle_status.msg这个uORB中的uint8 arming_state属性,实际上arming_state并不仅仅用于表示“锁定”和“解锁”这两个状态,它一共有6个状态也定义在vehicle_status.msg这个UORB当中,其内容如下:

uint8 ARMING_STATE_INIT = 0             //初始化
uint8 ARMING_STATE_STANDBY = 1          //准备就绪
uint8 ARMING_STATE_ARMED = 2            //已解锁
uint8 ARMING_STATE_STANDBY_ERROR = 3    //就绪错误
uint8 ARMING_STATE_REBOOT = 4           //重启
uint8 ARMING_STATE_IN_AIR_RESTORE = 5   //空中恢复

        实际上,Arming state是为了表示无人机在整个飞行过程中可能出现的基本状态,其中只有Arming state为ARMING_STATE_ARMED时,才表示飞控解锁,也就是电机解锁。用于表示飞控实际对电机“锁定”和“解锁”状态的变量并非Arming state,而是actuator_armed.msg这个uORB的bool armed属性。注意这个变量是一个布尔型变量,它只表示无人机系统“解锁”和“锁定”这两个状态。

        上述的6个状态切换图如下:

        在PX4程序中使用了一个二位数组来表示此状态机的切换关系,如下:

static const bool arming_transitions[vehicle_status_s::ARMING_STATE_MAX][vehicle_status_s::ARMING_STATE_MAX] = 
{
	//                                 INIT,  STANDBY, ARMED, STANDBY_ERROR, REBOOT, IN_AIR_RESTORE
	{ /*ARMING_STATE_INIT */           true,  true,    false, true,          false,  false },
	{ /*ARMING_STATE_STANDBY */        true,  true,    true,  false,         false,  false },
	{ /*ARMING_STATE_ARMED */          false, true,    true,  false,         false,  true  },
	{ /*ARMING_STATE_STANDBY_ERROR */  true,  true,    true,  true,          false,  false },
	{ /*ARMING_STATE_REBOOT */         true,  true,    false, true,          true,   true  },
	{ /*ARMING_STATE_IN_AIR_RESTORE */ false, false,   false, false,         false,  false }
};

        在这个表示Arming state的二位数组中,每一行表示无人机需要切换的新的状态,每一列表示当前状态。从当前状态切换到新状态时的限制条件就是arming_transitions这个二位数组的值,如果为true表示允许切换,如果为false表示不允许切换。

transition_result_t arming_state_transition(vehicle_status_s *status,
				const arming_state_t new_arming_state,
				actuator_armed_s *armed,
				vehicle_status_flags_s *status_flags,
				...)
{
	//允许切换标识
	transition_result_t ret = TRANSITION_DENIED;
	//当前状态
	arming_state_t current_arming_state = status->arming_state;
	//如果需要切换的新状态与当前状态相同,则不处理
	if (new_arming_state == current_arming_state)
	{
		ret = TRANSITION_NOT_CHANGED;
	}
	else
	{
		//检查状态切换结果
		bool valid_transition = arming_transitions[new_arming_state][status->arming_state];
		//如果允许切换
		if (valid_transition)
		{
			//设定“解锁”或“锁定”状态
			armed->armed = (new_arming_state == vehicle_status_s::ARMING_STATE_ARMED);
			//完成状态切换
			ret = TRANSITION_CHANGED;
			//更新Arming state为新状态
			status->arming_state = new_arming_state;
		}
	}
	return ret;
}

 

二、main_state主状态

        主状态就是我们之前所介绍的无人机的飞行模式。切换主状态就是切换飞行模式,使无人机进入不同的飞行控制逻辑当中。当然,飞控的主状态不可以任意切换,切换到不同的主状态需要不同的前提条件。每一种状态的条件前提我们可以按下表进行判断:

  多旋翼机 高度有效 本地坐标有效 全局坐标有效 任务有效 起飞点有效 数传信号有效
手动模式
增稳模式
特技模式
手动特技模式
高度控制模式
位置控制模式
悬停模式
任务模式
返航模式
起飞模式
着陆模式
目标跟随模式
离线模式

        用于表示主状态的变量被定义为commander_state.msg这个uORB中的uint8 main_state属性。其实际值与所表示的状态对应关系如下:

uint8 MAIN_STATE_MANUAL = 0                    //手动模式
uint8 MAIN_STATE_ALTCTL = 1                    //高度控制模式
uint8 MAIN_STATE_POSCTL = 2                    //位置控制模式
uint8 MAIN_STATE_AUTO_MISSION = 3              //任务模式
uint8 MAIN_STATE_AUTO_LOITER = 4               //悬停模式
uint8 MAIN_STATE_AUTO_RTL = 5                  //返航模式
uint8 MAIN_STATE_ACRO = 6                      //特技模式
uint8 MAIN_STATE_OFFBOARD = 7                  //离线模式
uint8 MAIN_STATE_STAB = 8                      //增稳模式
uint8 MAIN_STATE_RATTITUDE = 9                 //手动特技模式
uint8 MAIN_STATE_AUTO_TAKEOFF = 10             //起飞模式
uint8 MAIN_STATE_AUTO_LAND = 11                //着陆模式
uint8 MAIN_STATE_AUTO_FOLLOW_TARGET = 12       //目标跟随模式

        在主状态切换函数main_state_transition()处理了主状态的切换逻辑,具体代码如下:

transition_result_t main_state_transition(const vehicle_status_s &status,
		const main_state_t new_main_state,
		const vehicle_status_flags_s &status_flags,
		commander_state_s *internal_state)
{
	//切换结果,允许或拒绝
	transition_result_t ret = TRANSITION_DENIED;
	//需要切换的新主状态
	switch (new_main_state)
	{
		case commander_state_s::MAIN_STATE_MANUAL:
		case commander_state_s::MAIN_STATE_STAB:
		case commander_state_s::MAIN_STATE_ACRO:
		case commander_state_s::MAIN_STATE_RATTITUDE:
			ret = TRANSITION_CHANGED;
			break;
		case commander_state_s::MAIN_STATE_ALTCTL:
			if (status_flags.condition_local_altitude_valid
					|| status_flags.condition_global_position_valid)
				ret = TRANSITION_CHANGED;
			break;
		case commander_state_s::MAIN_STATE_POSCTL:
			if (status_flags.condition_local_position_valid
					|| status_flags.condition_global_position_valid)
				ret = TRANSITION_CHANGED;
			break;
		case commander_state_s::MAIN_STATE_AUTO_LOITER:
			if (status_flags.condition_global_position_valid)
				ret = TRANSITION_CHANGED;
			break;
		case commander_state_s::MAIN_STATE_AUTO_FOLLOW_TARGET:
			if (status.is_rotary_wing)
				ret = TRANSITION_CHANGED;
			break;
		case commander_state_s::MAIN_STATE_AUTO_MISSION:
			if (status_flags.condition_global_position_valid
					&& status_flags.condition_auto_mission_available)
				ret = TRANSITION_CHANGED;
			break;
		case commander_state_s::MAIN_STATE_AUTO_RTL:
			if (status_flags.condition_global_position_valid
					&& status_flags.condition_home_position_valid)
				ret = TRANSITION_CHANGED;
			break;
		case commander_state_s::MAIN_STATE_AUTO_TAKEOFF:
		case commander_state_s::MAIN_STATE_AUTO_LAND:
			if (status_flags.condition_local_position_valid)
				ret = TRANSITION_CHANGED;
			break;
		case commander_state_s::MAIN_STATE_AUTO_PRECLAND:
			if (status_flags.condition_local_position_valid
					&& status_flags.condition_global_position_valid
					&& status.is_rotary_wing)
				ret = TRANSITION_CHANGED;
			break;
		case commander_state_s::MAIN_STATE_OFFBOARD:
			if (!status_flags.offboard_control_signal_lost)
				ret = TRANSITION_CHANGED;
			break;
		case commander_state_s::MAIN_STATE_MAX:
		default:
			break;
	}
	//如果允许切换主状态,则修改主状态的值
	if (ret == TRANSITION_CHANGED)
		if (internal_state->main_state != new_main_state)
			internal_state->main_state = new_main_state;
		else
			ret = TRANSITION_NOT_CHANGED;
	return ret;
}

        以上代码中所处理的逻辑与上述表格中的内容一致,不再赘述。

 

三、导航状态

        导航状态被定义在vehicle_status.msg这个uORB的uint8 nav_state属性,其实际值与导航状态的对应关系如下:

uint8 NAVIGATION_STATE_MANUAL = 0                 //手动模式
uint8 NAVIGATION_STATE_ALTCTL = 1                 //高度控制模式
uint8 NAVIGATION_STATE_POSCTL = 2                 //位置控制模式
uint8 NAVIGATION_STATE_AUTO_MISSION = 3           //自动任务模式
uint8 NAVIGATION_STATE_AUTO_LOITER = 4            //自动悬停模式
uint8 NAVIGATION_STATE_AUTO_RTL = 5               //自动返航模式
uint8 NAVIGATION_STATE_AUTO_RCRECOVER = 6         //遥控器恢复
uint8 NAVIGATION_STATE_AUTO_RTGS = 7              //数传信号丢失自动返回地面站
uint8 NAVIGATION_STATE_AUTO_LANDENGFAIL = 8       //自动降落当引擎失效
uint8 NAVIGATION_STATE_AUTO_LANDGPSFAIL = 9       //自动降落当GPS失效
uint8 NAVIGATION_STATE_ACRO = 10                  //特级模式
uint8 NAVIGATION_STATE_UNUSED = 11                //预留
uint8 NAVIGATION_STATE_DESCEND = 12               //下降模式
uint8 NAVIGATION_STATE_TERMINATION = 13           //自毁模式
uint8 NAVIGATION_STATE_OFFBOARD = 14              //离线模式
uint8 NAVIGATION_STATE_STAB = 15                  //增稳模式
uint8 NAVIGATION_STATE_RATTITUDE = 16             //手动特技模式
uint8 NAVIGATION_STATE_AUTO_TAKEOFF = 17          //自动起飞模式
uint8 NAVIGATION_STATE_AUTO_LAND = 18             //自动着陆模式
uint8 NAVIGATION_STATE_AUTO_FOLLOW_TARGET = 19    //目标跟随模式
uint8 NAVIGATION_STATE_AUTO_PRECLAND = 20         //按目标精准着陆

        与主状态切换不同,无人机会根据当前状态与不同的条件对导航状态进行降级评估,也就是说如果当前飞行模式的必要条件如果不满足,则会切入到一个较为安全的导航状态。在正常情况下,导航状态值会被保持与主状态一致。

switch (internal_state->main_state)
{
	case commander_state_s::MAIN_STATE_ACRO:
		status->nav_state = vehicle_status_s::NAVIGATION_STATE_ACRO;
		break;
	case commander_state_s::MAIN_STATE_MANUAL:
		status->nav_state = vehicle_status_s::NAVIGATION_STATE_MANUAL;
		break;
	case commander_state_s::MAIN_STATE_RATTITUDE:
		status->nav_state = vehicle_status_s::NAVIGATION_STATE_RATTITUDE;
		break;
	case commander_state_s::MAIN_STATE_STAB:
		status->nav_state = vehicle_status_s::NAVIGATION_STATE_STAB;
		break;
	case commander_state_s::MAIN_STATE_ALTCTL:
		status->nav_state = vehicle_status_s::NAVIGATION_STATE_ALTCTL;
		break;
	...
	default:
		status->nav_state = vehicle_status_s::NAVIGATION_STATE_MANUAL;
		break;
}

        但是,在实际飞行中,会遇到很多异常情况,飞控程序会根据预先对相关保护参数的设定值修改导航状态,例如,当数传信号丢失后的处理方法如下:

void set_link_loss_nav_state(vehicle_status_s *status, actuator_armed_s *armed,
		const vehicle_status_flags_s &status_flags,
		commander_state_s *internal_state,
		const link_loss_actions_t link_loss_act,
		uint8_t auto_recovery_nav_state)
{
	//全局位置和起飞点有效时,自动恢复保护
	if (link_loss_act == link_loss_actions_t::AUTO_RECOVER
			&& status_flags.condition_global_position_valid
			&& status_flags.condition_home_position_valid)
	{
		status->nav_state = auto_recovery_nav_state;
	}
	//全局位置有效时,自动悬停
	else if (link_loss_act == link_loss_actions_t::AUTO_LOITER
			&& status_flags.condition_global_position_valid)
	{
		status->nav_state = vehicle_status_s::NAVIGATION_STATE_AUTO_LOITER;

	}
	//全局位置和起飞点有效时,自动返航
	else if (link_loss_act == link_loss_actions_t::AUTO_RTL
			&& status_flags.condition_global_position_valid
			&& status_flags.condition_home_position_valid)
	{
		main_state_transition(*status, commander_state_s::MAIN_STATE_AUTO_RTL,
				status_flags, internal_state);
		status->nav_state = vehicle_status_s::NAVIGATION_STATE_AUTO_RTL;
	}
	//本地位置有效时,自动降落
	else if (link_loss_act == link_loss_actions_t::AUTO_LAND
			&& status_flags.condition_local_position_valid)
	{
		status->nav_state = vehicle_status_s::NAVIGATION_STATE_AUTO_LAND;

	}
	//自毁
	else if (link_loss_act == link_loss_actions_t::TERMINATE)
	{
		status->nav_state = vehicle_status_s::NAVIGATION_STATE_TERMINATION;
		armed->force_failsafe = true;

	}
	//锁定
	else if (link_loss_act == link_loss_actions_t::LOCKDOWN)
	{
		armed->lockdown = true;
	}
	//全局位置和起飞点有效时,自动返航
	else if (status_flags.condition_global_position_valid
			&& status_flags.condition_home_position_valid)
	{
		status->nav_state = vehicle_status_s::NAVIGATION_STATE_AUTO_RTL;
	}
	//本地位置有效时自动降落
	else if (status_flags.condition_local_position_valid)
	{
		status->nav_state = vehicle_status_s::NAVIGATION_STATE_AUTO_LAND;
	}
	//高度有效时
	else if (status_flags.condition_local_altitude_valid)
	{
		//多旋翼自动下降
		if (status->is_rotary_wing)
		{
			status->nav_state = vehicle_status_s::NAVIGATION_STATE_DESCEND;
		}
		//自动降落当GPS失效
		else
		{
			status->nav_state = vehicle_status_s::NAVIGATION_STATE_AUTO_LANDGPSFAIL;
		}
	}
	//自毁
	else
	{
		status->nav_state = vehicle_status_s::NAVIGATION_STATE_TERMINATION;
	}
}

 

    返回首页    返回顶部
  看不清?点击刷新

 

  Copyright © 2015-2023 问渠网 辽ICP备15013245号