Skip to content

Commit

Permalink
Navigator/FlightTaskAuto yaw handling improvements/simplifications (P…
Browse files Browse the repository at this point in the history
…X4#22532)

* PositionSetpoint: remove yaw_valid field

* Navigator: set yaw setpoint to NAN for Takeoff

Don't set a yaw setpoint for takeoff, as Navigator doesn't handle the yaw reset.
The yaw setpoint generation is handled by FlightTaskAuto.

* PositionSetpoint.msg: remove disable_weather_vane and instead only use the yaw field

Strictly follow the concept that if the position_setpoint.yaw is set, then
follow it the controller, and otherwise let the controller set it as it
thinks it's best.

* Navigator: remove logic that sets yaw to be accepted in TAKEOFF

No longer needed as during Takeoff we anyway don't set a yaw setpoint.

* PositionSetpoint.msg: remove yawspeed_valid

* PositionSetpoint.msg: remove yawspeed

* Navigator: set yaw setpoint to NAN instead of current

In set_takeoff and set_land_item, as well as for VTOL transition.
The flight tasks then set the yaw corresponding to the current yaw.

* Navigator: change get_yaw_acceptance into a bool

* PositionSetpoint.msg: improve comment for yaw

* MissionBlock: remove unnecessary code from set_vtol_transition_item

* Navigator: clean up calculate_breaking_stop(), set yaw to NAN

* Navigator: set yaw to NAN in variouls places where not specifc setpoint is desired

* Navigator: set yaw to NAN in reset_position_setpoint()

---------

Signed-off-by: Silvan Fuhrer <silvan@auterion.com>
Co-authored-by: Matthias Grob <maetugr@gmail.com>
  • Loading branch information
sfuhrer and MaEtUgR authored Dec 21, 2023
1 parent d872ef8 commit 7e22b47
Show file tree
Hide file tree
Showing 9 changed files with 38 additions and 90 deletions.
8 changes: 1 addition & 7 deletions msg/PositionSetpoint.msg
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,7 @@ float32 vz # local velocity setpoint in m/s in NED
float64 lat # latitude, in deg
float64 lon # longitude, in deg
float32 alt # altitude AMSL, in m
float32 yaw # yaw (only for multirotors), in rad [-PI..PI), NaN = hold current yaw
bool yaw_valid # true if yaw setpoint valid

float32 yawspeed # yawspeed (only for multirotors, in rad/s)
bool yawspeed_valid # true if yawspeed setpoint valid
float32 yaw # yaw (only in hover), in rad [-PI..PI), NaN = leave to flight task

float32 loiter_radius # loiter major axis radius in m
float32 loiter_minor_radius # loiter minor axis radius (used for non-circular loiter shapes) in m
Expand All @@ -39,5 +35,3 @@ float32 acceptance_radius # navigation acceptance_radius if we're doing waypoi
float32 cruising_speed # the generally desired cruising speed (not a hard constraint)
bool gliding_enabled # commands the vehicle to glide if the capability is available (fixed wing only)
float32 cruising_throttle # the generally desired cruising throttle (not a hard constraint), only has an effect for rover

bool disable_weather_vane # VTOL: disable (in auto mode) the weather vane feature that turns the nose into the wind
12 changes: 3 additions & 9 deletions src/modules/flight_mode_manager/tasks/Auto/FlightTaskAuto.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -466,7 +466,7 @@ bool FlightTaskAuto::_evaluateTriplets()
}

// activation/deactivation of weather vane is based on parameter WV_EN and setting of navigator (allow_weather_vane)
_weathervane.setNavigatorForceDisabled(_sub_triplet_setpoint.get().current.disable_weather_vane);
_weathervane.setNavigatorForceDisabled(PX4_ISFINITE(_sub_triplet_setpoint.get().current.yaw));

// Calculate the current vehicle state and check if it has updated.
State previous_state = _current_state;
Expand All @@ -481,7 +481,7 @@ bool FlightTaskAuto::_evaluateTriplets()
_obstacle_avoidance.updateAvoidanceDesiredWaypoints(_triplet_target, _yaw_setpoint, _yawspeed_setpoint,
_triplet_next_wp,
_sub_triplet_setpoint.get().next.yaw,
_sub_triplet_setpoint.get().next.yawspeed_valid ? _sub_triplet_setpoint.get().next.yawspeed : (float)NAN,
(float)NAN,
_weathervane.isActive(), _sub_triplet_setpoint.get().current.type);
_obstacle_avoidance.checkAvoidanceProgress(
_position, _triplet_prev_wp, _target_acceptance_radius, Vector2f(_closest_pt));
Expand Down Expand Up @@ -509,13 +509,7 @@ bool FlightTaskAuto::_evaluateTriplets()
_yaw_setpoint = NAN;
_yawspeed_setpoint = 0.f;

} else if ((_type != WaypointType::takeoff || _sub_triplet_setpoint.get().current.disable_weather_vane)
&& _sub_triplet_setpoint.get().current.yaw_valid) {
// Use the yaw computed in Navigator except during takeoff because
// Navigator is not handling the yaw reset properly.
// But: use if from Navigator during takeoff if disable_weather_vane is true,
// because we're then aligning to the transition waypoint.
// TODO: fix in navigator
} else if (PX4_ISFINITE(_sub_triplet_setpoint.get().current.yaw)) {
_yaw_setpoint = _sub_triplet_setpoint.get().current.yaw;
_yawspeed_setpoint = NAN;

Expand Down
17 changes: 2 additions & 15 deletions src/modules/navigator/mission.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -322,8 +322,7 @@ void Mission::handleTakeoff(WorkItemType &new_work_item_type, mission_item_s nex

_mission_item.lat = _global_pos_sub.get().lat;
_mission_item.lon = _global_pos_sub.get().lon;
/* hold heading for takeoff items */
_mission_item.yaw = _navigator->get_local_position()->heading;
_mission_item.yaw = NAN; // FlightTaskAuto handles yaw directly
_mission_item.altitude = _mission_init_climb_altitude_amsl;
_mission_item.altitude_is_relative = false;
_mission_item.autocontinue = true;
Expand Down Expand Up @@ -366,9 +365,6 @@ void Mission::handleTakeoff(WorkItemType &new_work_item_type, mission_item_s nex
_vehicle_status_sub.get().vehicle_type == vehicle_status_s::VEHICLE_TYPE_ROTARY_WING &&
!_land_detected_sub.get().landed) {

/* disable weathervane before front transition for allowing yaw to align */
pos_sp_triplet->current.disable_weather_vane = true;

/* set yaw setpoint to heading of VTOL_TAKEOFF wp against current position */
_mission_item.yaw = get_bearing_to_next_waypoint(
_global_pos_sub.get().lat, _global_pos_sub.get().lon,
Expand All @@ -389,16 +385,13 @@ void Mission::handleTakeoff(WorkItemType &new_work_item_type, mission_item_s nex
_vehicle_status_sub.get().vehicle_type == vehicle_status_s::VEHICLE_TYPE_ROTARY_WING &&
!_land_detected_sub.get().landed) {

/* re-enable weather vane again after alignment */
pos_sp_triplet->current.disable_weather_vane = false;

/* check if the vtol_takeoff waypoint is on top of us */
if (do_need_move_to_takeoff()) {
new_work_item_type = WorkItemType::WORK_ITEM_TYPE_TRANSITION_AFTER_TAKEOFF;
}

set_vtol_transition_item(&_mission_item, vtol_vehicle_status_s::VEHICLE_VTOL_STATE_FW);
_mission_item.yaw = _navigator->get_local_position()->heading;
_mission_item.yaw = NAN;

// keep current setpoints (FW position controller generates wp to track during transition)
pos_sp_triplet->current.type = position_setpoint_s::SETPOINT_TYPE_POSITION;
Expand Down Expand Up @@ -428,9 +421,6 @@ void Mission::handleVtolTransition(WorkItemType &new_work_item_type, mission_ite
&& !_land_detected_sub.get().landed
&& (num_found_items > 0u)) {

/* disable weathervane before front transition for allowing yaw to align */
pos_sp_triplet->current.disable_weather_vane = true;

new_work_item_type = WorkItemType::WORK_ITEM_TYPE_ALIGN_HEADING;

set_align_mission_item(&_mission_item, &next_mission_items[0u]);
Expand All @@ -445,9 +435,6 @@ void Mission::handleVtolTransition(WorkItemType &new_work_item_type, mission_ite

new_work_item_type = WorkItemType::WORK_ITEM_TYPE_DEFAULT;

/* re-enable weather vane again after alignment */
pos_sp_triplet->current.disable_weather_vane = false;

pos_sp_triplet->previous = pos_sp_triplet->current;
// keep current setpoints (FW position controller generates wp to track during transition)
pos_sp_triplet->current.type = position_setpoint_s::SETPOINT_TYPE_POSITION;
Expand Down
9 changes: 2 additions & 7 deletions src/modules/navigator/mission_base.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -654,9 +654,6 @@ bool MissionBase::position_setpoint_equal(const position_setpoint_s *p1, const p
(fabs(p1->lon - p2->lon) < DBL_EPSILON) &&
(fabsf(p1->alt - p2->alt) < FLT_EPSILON) &&
((fabsf(p1->yaw - p2->yaw) < FLT_EPSILON) || (!PX4_ISFINITE(p1->yaw) && !PX4_ISFINITE(p2->yaw))) &&
(p1->yaw_valid == p2->yaw_valid) &&
(fabsf(p1->yawspeed - p2->yawspeed) < FLT_EPSILON) &&
(p1->yawspeed_valid == p2->yawspeed_valid) &&
(fabsf(p1->loiter_radius - p2->loiter_radius) < FLT_EPSILON) &&
(p1->loiter_direction_counter_clockwise == p2->loiter_direction_counter_clockwise) &&
(fabsf(p1->acceptance_radius - p2->acceptance_radius) < FLT_EPSILON) &&
Expand Down Expand Up @@ -773,13 +770,11 @@ MissionBase::heading_sp_update()

_mission_item.yaw = yaw;
pos_sp_triplet->current.yaw = _mission_item.yaw;
pos_sp_triplet->current.yaw_valid = true;

} else {
if (!pos_sp_triplet->current.yaw_valid) {
_mission_item.yaw = _navigator->get_local_position()->heading;
if (!PX4_ISFINITE(pos_sp_triplet->current.yaw)) {
_mission_item.yaw = NAN;
pos_sp_triplet->current.yaw = _mission_item.yaw;
pos_sp_triplet->current.yaw_valid = true;
}
}

Expand Down
34 changes: 12 additions & 22 deletions src/modules/navigator/mission_block.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,7 @@ MissionBlock::is_mission_item_reached_or_completed()
if (_waypoint_position_reached && !_waypoint_yaw_reached) {

if (_navigator->get_vstatus()->vehicle_type == vehicle_status_s::VEHICLE_TYPE_ROTARY_WING
&& PX4_ISFINITE(_navigator->get_yaw_acceptance(_mission_item.yaw))
&& _navigator->get_yaw_to_be_accepted(_mission_item.yaw)
&& _navigator->get_local_position()->heading_good_for_control) {

const float yaw_err = wrap_pi(_mission_item.yaw - _navigator->get_local_position()->heading);
Expand All @@ -423,14 +423,6 @@ MissionBlock::is_mission_item_reached_or_completed()
_waypoint_yaw_reached = true;
}

// Always accept yaw during takeoff
// TODO: Ideally Navigator would handle a yaw reset and adjust its yaw setpoint, making the
// following no longer necessary.
// FlightTaskAuto is currently also ignoring the yaw setpoint during takeoff and thus "handling" it.
if (_mission_item.nav_cmd == vehicle_command_s::VEHICLE_CMD_NAV_TAKEOFF) {
_waypoint_yaw_reached = true;
}

/* if heading needs to be reached, the timeout is enabled and we don't make it, abort mission */
if (!_waypoint_yaw_reached && _mission_item.force_heading &&
(_navigator->get_yaw_timeout() >= FLT_EPSILON) &&
Expand Down Expand Up @@ -668,7 +660,6 @@ MissionBlock::mission_item_to_position_setpoint(const mission_item_s &item, posi
sp->lon = item.lon;
sp->alt = get_absolute_altitude_for_item(item);
sp->yaw = item.yaw;
sp->yaw_valid = PX4_ISFINITE(item.yaw);
sp->loiter_radius = (fabsf(item.loiter_radius) > NAV_EPSILON_POSITION) ? fabsf(item.loiter_radius) :
_navigator->get_loiter_radius();
sp->loiter_direction_counter_clockwise = item.loiter_radius < 0;
Expand Down Expand Up @@ -704,6 +695,10 @@ MissionBlock::mission_item_to_position_setpoint(const mission_item_s &item, posi

} else {
sp->type = position_setpoint_s::SETPOINT_TYPE_TAKEOFF;

// Don't set a yaw setpoint for takeoff, as Navigator doesn't handle the yaw reset.
// The yaw setpoint generation is handled by FlightTaskAuto.
sp->yaw = NAN;
}

break;
Expand Down Expand Up @@ -746,6 +741,7 @@ MissionBlock::setLoiterItemFromCurrentPositionSetpoint(struct mission_item_s *it
item->altitude = pos_sp_triplet->current.alt;
item->loiter_radius = pos_sp_triplet->current.loiter_direction_counter_clockwise ?
-pos_sp_triplet->current.loiter_radius : pos_sp_triplet->current.loiter_radius;
item->yaw = pos_sp_triplet->current.yaw;
}

void
Expand All @@ -765,19 +761,20 @@ MissionBlock::setLoiterItemFromCurrentPosition(struct mission_item_s *item)
}

item->altitude = loiter_altitude_amsl;

item->loiter_radius = _navigator->get_loiter_radius();
item->yaw = NAN;
}

void
MissionBlock::setLoiterItemFromCurrentPositionWithBreaking(struct mission_item_s *item)
{
setLoiterItemCommonFields(item);

_navigator->calculate_breaking_stop(item->lat, item->lon, item->yaw);
_navigator->calculate_breaking_stop(item->lat, item->lon);

item->altitude = _navigator->get_global_position()->alt;
item->loiter_radius = _navigator->get_loiter_radius();
item->yaw = NAN;
}

void
Expand All @@ -801,7 +798,7 @@ MissionBlock::set_takeoff_item(struct mission_item_s *item, float abs_altitude)
/* use current position */
item->lat = _navigator->get_global_position()->lat;
item->lon = _navigator->get_global_position()->lon;
item->yaw = _navigator->get_local_position()->heading;
item->yaw = NAN;

item->altitude = abs_altitude;
item->altitude_is_relative = false;
Expand Down Expand Up @@ -831,7 +828,7 @@ MissionBlock::set_land_item(struct mission_item_s *item)
// set land item to current position
item->lat = _navigator->get_global_position()->lat;
item->lon = _navigator->get_global_position()->lon;
item->yaw = _navigator->get_local_position()->heading;
item->yaw = NAN;

item->altitude = 0;
item->altitude_is_relative = false;
Expand Down Expand Up @@ -863,14 +860,7 @@ MissionBlock::set_vtol_transition_item(struct mission_item_s *item, const uint8_
{
item->nav_cmd = NAV_CMD_DO_VTOL_TRANSITION;
item->params[0] = (float) new_mode;
item->params[1] = 0.0f;

// Keep yaw from previous mission item if valid, as that is containing the transition heading.
// If not valid use current yaw as yaw setpoint
if (!PX4_ISFINITE(item->yaw)) {
item->yaw = _navigator->get_local_position()->heading; // ideally that would be course and not heading
}

item->params[1] = 0.0f; // not immediate transition
item->autocontinue = true;
}

Expand Down
9 changes: 4 additions & 5 deletions src/modules/navigator/navigator.h
Original file line number Diff line number Diff line change
Expand Up @@ -239,14 +239,13 @@ class Navigator : public ModuleBase<Navigator>, public ModuleParams
void set_cruising_throttle(float throttle = NAN) { _mission_throttle = throttle; }

/**
* Get the yaw acceptance given the current mission item
* Get if the yaw acceptance is required at the current mission item
*
* @param mission_item_yaw the yaw to use in case the controller-derived radius is finite
*
* @return the yaw at which the next waypoint should be used or NaN if the yaw at a waypoint
* should be ignored
* @return true if the yaw acceptance is required, false if not required
*/
float get_yaw_acceptance(float mission_item_yaw);
bool get_yaw_to_be_accepted(float mission_item_yaw);

orb_advert_t *get_mavlink_log_pub() { return &_mavlink_log_pub; }

Expand Down Expand Up @@ -279,7 +278,7 @@ class Navigator : public ModuleBase<Navigator>, public ModuleParams
void release_gimbal_control();
void set_gimbal_neutral();

void calculate_breaking_stop(double &lat, double &lon, float &yaw);
void calculate_breaking_stop(double &lat, double &lon);

void stop_capturing_images();
void disable_camera_trigger();
Expand Down
Loading

0 comments on commit 7e22b47

Please sign in to comment.