起飞部分
首先默认以MANUAL_CTRL进如状态机
接收到起飞信号后
在/px4ctrl/src/PX4CtrlFSM.cpp的状态机中进行状态转换由MANUAL_CTRL状态转到AUTO_TAKEOFF状态并控制px4切换到offboard模式并解锁。(117行)
state = AUTO_TAKEOFF;
controller.resetThrustMapping();
set_start_pose_for_takeoff_land(odom_data);
toggle_offboard_mode(true); // toggle on offboard before arm
for (int i = 0; i < 10 && ros::ok(); ++i) // wait for 0.1 seconds to allow mode change by FMU // mark
{
ros::Duration(0.01).sleep();
ros::spinOnce();
}
if (param.takeoff_land.enable_auto_arm)
{
toggle_arm_disarm(true);
}
takeoff_land.toggle_takeoff_land_time = now_time;
进入AUTO_TAKEOFF状态
在该段代码中首先电机旋转 AutoTakeoffLand_t::MOTORS_SPEEDUP_TIME 设定的时间长度。
case AUTO_TAKEOFF:
{
if ((now_time - takeoff_land.toggle_takeoff_land_time).toSec() < AutoTakeoffLand_t::MOTORS_SPEEDUP_TIME) // Wait for several seconds to warn prople.
{
des = get_rotor_speed_up_des(now_time);
}
else if (odom_data.p(2) >= (takeoff_land.start_pose(2) + param.takeoff_land.height)) // reach the desired height
{
state = AUTO_HOVER;
set_hov_with_odom();
ROS_INFO("\033[32m[px4ctrl] AUTO_TAKEOFF --> AUTO_HOVER(L2)\033[32m");
takeoff_land.delay_trigger.first = true;
takeoff_land.delay_trigger.second = now_time + ros::Duration(AutoTakeoffLand_t::DELAY_TRIGGER_TIME);
}
else
{
des = get_takeoff_land_des(param.takeoff_land.speed);
}
break;
}
接下来进入 get_rotor_speed_up_des(now_time);计算旋翼速度增加过程中的期望状态,包括位置、速度、加速度、偏航角度和偏航角速率。
Desired_State_t PX4CtrlFSM::get_rotor_speed_up_des(const ros::Time now)
{
double delta_t = (now - takeoff_land.toggle_takeoff_land_time).toSec();
double des_a_z = exp((delta_t - AutoTakeoffLand_t::MOTORS_SPEEDUP_TIME) * 6.0) * 7.0 - 7.0; // Parameters 6.0 and 7.0 are just heuristic values which result in a saticfactory curve.
if (des_a_z > 0.1)
{
ROS_ERROR("des_a_z > 0.1!, des_a_z=%f", des_a_z);
des_a_z = 0.0;
}
Desired_State_t des;
des.p = takeoff_land.start_pose.head<3>();
des.v = Eigen::Vector3d::Zero();
des.a = Eigen::Vector3d(0, 0, des_a_z);
des.j = Eigen::Vector3d::Zero();
des.yaw = takeoff_land.start_pose(3);
des.yaw_rate = 0.0;
return des;
}
电机空转结束后进入起飞状态进入get_takeoff_land_des(const double speed), 这个函数的主要目的是根据起飞或降落的切换时间、速度以及位置更新公式,计算起飞或降落过程中的期望状态,包括位置、速度、加速度、偏航角度和偏航角速率。
Desired_State_t PX4CtrlFSM::get_takeoff_land_des(const double speed)
{
ros::Time now = ros::Time::now();
double delta_t = (now - takeoff_land.toggle_takeoff_land_time).toSec() - (speed > 0 ? AutoTakeoffLand_t::MOTORS_SPEEDUP_TIME : 0); // speed > 0 means takeoff
// takeoff_land.last_set_cmd_time = now;
// takeoff_land.start_pose(2) += speed * delta_t;
Desired_State_t des;
des.p = takeoff_land.start_pose.head<3>() + Eigen::Vector3d(0, 0, speed * delta_t);
des.v = Eigen::Vector3d(0, 0, speed);
des.a = Eigen::Vector3d::Zero();
des.j = Eigen::Vector3d::Zero();
des.yaw = takeoff_land.start_pose(3);
des.yaw_rate = 0.0;
return des;
}
当到达指定高度时进行一个设定好的延时则进入悬停状态
else if (odom_data.p(2) >= (takeoff_land.start_pose(2) + param.takeoff_land.height)) // reach the desired height
{
state = AUTO_HOVER;
set_hov_with_odom();
ROS_INFO("\033[32m[px4ctrl] AUTO_TAKEOFF --> AUTO_HOVER(L2)\033[32m");
takeoff_land.delay_trigger.first = true;
takeoff_land.delay_trigger.second = now_time + ros::Duration(AutoTakeoffLand_t::DELAY_TRIGGER_TIME);
}