mirror of
https://github.com/PX4/PX4-Autopilot.git
synced 2026-06-01 02:55:07 +08:00
FlightModeManager: handle commands all the time
Moving the command handling to a separate function that gets called whenever a vehicle command is available to always react on commands and not just when already a task is running. This solves e.g. commanding an Orbit when in Staibilized.
This commit is contained in:
committed by
Lorenz Meier
parent
df54f938ef
commit
031bbb7f3e
@@ -141,6 +141,10 @@ void FlightModeManager::Run()
|
|||||||
|
|
||||||
start_flight_task();
|
start_flight_task();
|
||||||
|
|
||||||
|
if (_vehicle_command_sub.updated()) {
|
||||||
|
handleCommand();
|
||||||
|
}
|
||||||
|
|
||||||
if (isAnyTaskActive()) {
|
if (isAnyTaskActive()) {
|
||||||
generateTrajectorySetpoint(dt, vehicle_local_position);
|
generateTrajectorySetpoint(dt, vehicle_local_position);
|
||||||
}
|
}
|
||||||
@@ -433,53 +437,52 @@ void FlightModeManager::send_vehicle_cmd_do(uint8_t nav_state)
|
|||||||
_vehicle_command_pub.publish(command);
|
_vehicle_command_pub.publish(command);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FlightModeManager::handleCommand()
|
||||||
|
{
|
||||||
|
// get command
|
||||||
|
vehicle_command_s command{};
|
||||||
|
_vehicle_command_sub.copy(&command);
|
||||||
|
|
||||||
|
// check what command it is
|
||||||
|
FlightTaskIndex desired_task = switchVehicleCommand(command.command);
|
||||||
|
|
||||||
|
// ignore all unkown commands
|
||||||
|
if (desired_task != FlightTaskIndex::None) {
|
||||||
|
// switch to the commanded task
|
||||||
|
FlightTaskError switch_result = switchTask(desired_task);
|
||||||
|
uint8_t cmd_result = vehicle_command_ack_s::VEHICLE_RESULT_FAILED;
|
||||||
|
|
||||||
|
// if we are in/switched to the desired task
|
||||||
|
if (switch_result >= FlightTaskError::NoError) {
|
||||||
|
cmd_result = vehicle_command_ack_s::VEHICLE_RESULT_ACCEPTED;
|
||||||
|
|
||||||
|
// if the task is running apply parameters to it and see if it rejects
|
||||||
|
if (isAnyTaskActive() && !_current_task.task->applyCommandParameters(command)) {
|
||||||
|
cmd_result = vehicle_command_ack_s::VEHICLE_RESULT_DENIED;
|
||||||
|
|
||||||
|
// if we just switched and parameters are not accepted, go to failsafe
|
||||||
|
if (switch_result >= FlightTaskError::NoError) {
|
||||||
|
switchTask(FlightTaskIndex::ManualPosition);
|
||||||
|
cmd_result = vehicle_command_ack_s::VEHICLE_RESULT_FAILED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// send back acknowledgment
|
||||||
|
vehicle_command_ack_s command_ack{};
|
||||||
|
command_ack.command = command.command;
|
||||||
|
command_ack.result = cmd_result;
|
||||||
|
command_ack.result_param1 = static_cast<int>(switch_result);
|
||||||
|
command_ack.target_system = command.source_system;
|
||||||
|
command_ack.target_component = command.source_component;
|
||||||
|
command_ack.timestamp = hrt_absolute_time();
|
||||||
|
_vehicle_command_ack_pub.publish(command_ack);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void FlightModeManager::generateTrajectorySetpoint(const float dt,
|
void FlightModeManager::generateTrajectorySetpoint(const float dt,
|
||||||
const vehicle_local_position_s &vehicle_local_position)
|
const vehicle_local_position_s &vehicle_local_position)
|
||||||
{
|
{
|
||||||
// In case flight task was not able to update correctly we send the empty setpoint which makes the position controller failsafe.
|
|
||||||
if (_vehicle_command_sub.updated()) {
|
|
||||||
// get command
|
|
||||||
vehicle_command_s command{};
|
|
||||||
_vehicle_command_sub.copy(&command);
|
|
||||||
|
|
||||||
// check what command it is
|
|
||||||
FlightTaskIndex desired_task = switchVehicleCommand(command.command);
|
|
||||||
|
|
||||||
// ignore all unkown commands
|
|
||||||
if (desired_task != FlightTaskIndex::None) {
|
|
||||||
// switch to the commanded task
|
|
||||||
FlightTaskError switch_result = switchTask(desired_task);
|
|
||||||
uint8_t cmd_result = vehicle_command_ack_s::VEHICLE_RESULT_FAILED;
|
|
||||||
|
|
||||||
// if we are in/switched to the desired task
|
|
||||||
if (switch_result >= FlightTaskError::NoError) {
|
|
||||||
cmd_result = vehicle_command_ack_s::VEHICLE_RESULT_ACCEPTED;
|
|
||||||
|
|
||||||
// if the task is running apply parameters to it and see if it rejects
|
|
||||||
if (isAnyTaskActive() && !_current_task.task->applyCommandParameters(command)) {
|
|
||||||
cmd_result = vehicle_command_ack_s::VEHICLE_RESULT_DENIED;
|
|
||||||
|
|
||||||
// if we just switched and parameters are not accepted, go to failsafe
|
|
||||||
if (switch_result >= FlightTaskError::NoError) {
|
|
||||||
switchTask(FlightTaskIndex::ManualPosition);
|
|
||||||
cmd_result = vehicle_command_ack_s::VEHICLE_RESULT_FAILED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// send back acknowledgment
|
|
||||||
vehicle_command_ack_s command_ack{};
|
|
||||||
command_ack.command = command.command;
|
|
||||||
command_ack.result = cmd_result;
|
|
||||||
command_ack.result_param1 = static_cast<int>(switch_result);
|
|
||||||
command_ack.target_system = command.source_system;
|
|
||||||
command_ack.target_component = command.source_component;
|
|
||||||
command_ack.timestamp = hrt_absolute_time();
|
|
||||||
_vehicle_command_ack_pub.publish(command_ack);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
_current_task.task->setYawHandler(_wv_controller);
|
_current_task.task->setYawHandler(_wv_controller);
|
||||||
|
|
||||||
// Inform FlightTask about the input and output of the velocity controller
|
// Inform FlightTask about the input and output of the velocity controller
|
||||||
@@ -494,7 +497,7 @@ void FlightModeManager::generateTrajectorySetpoint(const float dt,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// initialize with empty NAN setpoints, if the task fails they get sent out and controller's emergency failsafe kicks in
|
// If the task fails sned out empty NAN setpoints and the controller will emergency failsafe
|
||||||
vehicle_local_position_setpoint_s setpoint = FlightTask::empty_setpoint;
|
vehicle_local_position_setpoint_s setpoint = FlightTask::empty_setpoint;
|
||||||
vehicle_constraints_s constraints = FlightTask::empty_constraints;
|
vehicle_constraints_s constraints = FlightTask::empty_constraints;
|
||||||
|
|
||||||
|
|||||||
@@ -90,6 +90,7 @@ private:
|
|||||||
void start_flight_task();
|
void start_flight_task();
|
||||||
void check_failure(bool task_failure, uint8_t nav_state);
|
void check_failure(bool task_failure, uint8_t nav_state);
|
||||||
void send_vehicle_cmd_do(uint8_t nav_state);
|
void send_vehicle_cmd_do(uint8_t nav_state);
|
||||||
|
void handleCommand();
|
||||||
void generateTrajectorySetpoint(const float dt, const vehicle_local_position_s &vehicle_local_position);
|
void generateTrajectorySetpoint(const float dt, const vehicle_local_position_s &vehicle_local_position);
|
||||||
void limitAltitude(vehicle_local_position_setpoint_s &setpoint, const vehicle_local_position_s &vehicle_local_position);
|
void limitAltitude(vehicle_local_position_setpoint_s &setpoint, const vehicle_local_position_s &vehicle_local_position);
|
||||||
void reset_setpoint_to_nan(vehicle_local_position_setpoint_s &setpoint);
|
void reset_setpoint_to_nan(vehicle_local_position_setpoint_s &setpoint);
|
||||||
|
|||||||
Reference in New Issue
Block a user