Copter: FlightMode - convert POSHOLD flight mode

This commit is contained in:
Peter Barker 2016-03-23 11:51:39 +11:00 committed by Randy Mackay
parent 67063d6b1e
commit cafce01357
4 changed files with 61 additions and 35 deletions

View File

@ -788,15 +788,6 @@ private:
void land_run_horizontal_control(); void land_run_horizontal_control();
void set_mode_land_with_pause(mode_reason_t reason); void set_mode_land_with_pause(mode_reason_t reason);
bool landing_with_GPS(); bool landing_with_GPS();
bool poshold_init(bool ignore_checks);
void poshold_run();
void poshold_update_pilot_lean_angle(float &lean_angle_filtered, float &lean_angle_raw);
int16_t poshold_mix_controls(float mix_ratio, int16_t first_control, int16_t second_control);
void poshold_update_brake_angle_from_velocity(int16_t &brake_angle, float velocity);
void poshold_update_wind_comp_estimate();
void poshold_get_wind_comp_lean_angles(int16_t &roll_angle, int16_t &pitch_angle);
void poshold_roll_controller_to_pilot_override();
void poshold_pitch_controller_to_pilot_override();
// Throw to launch functionality // Throw to launch functionality
bool throw_init(bool ignore_checks); bool throw_init(bool ignore_checks);
@ -1039,6 +1030,10 @@ private:
Copter::FlightMode_LOITER flightmode_loiter{*this}; Copter::FlightMode_LOITER flightmode_loiter{*this};
#if POSHOLD_ENABLED == ENABLED
Copter::FlightMode_POSHOLD flightmode_poshold{*this};
#endif
Copter::FlightMode_RTL flightmode_rtl{*this}; Copter::FlightMode_RTL flightmode_rtl{*this};
#if FRAME_CONFIG == HELI_FRAME #if FRAME_CONFIG == HELI_FRAME

View File

@ -729,3 +729,40 @@ private:
bool autotune_currently_level(); bool autotune_currently_level();
}; };
#endif #endif
#if POSHOLD_ENABLED == ENABLED
class FlightMode_POSHOLD : public FlightMode {
public:
FlightMode_POSHOLD(Copter &copter) :
Copter::FlightMode(copter)
{ }
bool init(bool ignore_checks) override;
void run() override; // should be called at 100hz or more
bool requires_GPS() const override { return true; }
bool has_manual_throttle() const override { return false; }
bool allows_arming(bool from_gcs) const override { return true; };
bool is_autopilot() const override { return false; }
protected:
const char *name() const override { return "POSHOLD"; }
const char *name4() const override { return "PHLD"; }
private:
void poshold_update_pilot_lean_angle(float &lean_angle_filtered, float &lean_angle_raw);
int16_t poshold_mix_controls(float mix_ratio, int16_t first_control, int16_t second_control);
void poshold_update_brake_angle_from_velocity(int16_t &brake_angle, float velocity);
void poshold_update_wind_comp_estimate();
void poshold_get_wind_comp_lean_angles(int16_t &roll_angle, int16_t &pitch_angle);
void poshold_roll_controller_to_pilot_override();
void poshold_pitch_controller_to_pilot_override();
};
#endif

View File

@ -73,10 +73,10 @@ static struct {
} poshold; } poshold;
// poshold_init - initialise PosHold controller // poshold_init - initialise PosHold controller
bool Copter::poshold_init(bool ignore_checks) bool Copter::FlightMode_POSHOLD::init(bool ignore_checks)
{ {
// fail to initialise PosHold mode if no GPS lock // fail to initialise PosHold mode if no GPS lock
if (!position_ok() && !ignore_checks) { if (!_copter.position_ok() && !ignore_checks) {
return false; return false;
} }
@ -124,7 +124,7 @@ bool Copter::poshold_init(bool ignore_checks)
// poshold_run - runs the PosHold controller // poshold_run - runs the PosHold controller
// should be called at 100hz or more // should be called at 100hz or more
void Copter::poshold_run() void Copter::FlightMode_POSHOLD::run()
{ {
float target_roll, target_pitch; // pilot's roll and pitch angle inputs float target_roll, target_pitch; // pilot's roll and pitch angle inputs
float target_yaw_rate = 0; // pilot desired yaw rate in centi-degrees/sec float target_yaw_rate = 0; // pilot desired yaw rate in centi-degrees/sec
@ -150,7 +150,7 @@ void Copter::poshold_run()
} }
// process pilot inputs // process pilot inputs
if (!failsafe.radio) { if (!_copter.failsafe.radio) {
// apply SIMPLE mode transform to pilot inputs // apply SIMPLE mode transform to pilot inputs
update_simple_mode(); update_simple_mode();
@ -204,7 +204,7 @@ void Copter::poshold_run()
return; return;
}else{ }else{
// convert pilot input to lean angles // convert pilot input to lean angles
get_pilot_desired_lean_angles(channel_roll->get_control_in(), channel_pitch->get_control_in(), target_roll, target_pitch, aparm.angle_max); get_pilot_desired_lean_angles(channel_roll->get_control_in(), channel_pitch->get_control_in(), target_roll, target_pitch, _copter.aparm.angle_max);
// convert inertial nav earth-frame velocities to body-frame // convert inertial nav earth-frame velocities to body-frame
// To-Do: move this to AP_Math (or perhaps we already have a function to do this) // To-Do: move this to AP_Math (or perhaps we already have a function to do this)
@ -520,14 +520,15 @@ void Copter::poshold_run()
} }
// constrain target pitch/roll angles // constrain target pitch/roll angles
poshold.roll = constrain_int16(poshold.roll, -aparm.angle_max, aparm.angle_max); float angle_max = _copter.aparm.angle_max;
poshold.pitch = constrain_int16(poshold.pitch, -aparm.angle_max, aparm.angle_max); poshold.roll = constrain_int16(poshold.roll, -angle_max, angle_max);
poshold.pitch = constrain_int16(poshold.pitch, -angle_max, angle_max);
// update attitude controller targets // update attitude controller targets
attitude_control->input_euler_angle_roll_pitch_euler_rate_yaw(poshold.roll, poshold.pitch, target_yaw_rate, get_smoothing_gain()); attitude_control->input_euler_angle_roll_pitch_euler_rate_yaw(poshold.roll, poshold.pitch, target_yaw_rate, get_smoothing_gain());
// adjust climb rate using rangefinder // adjust climb rate using rangefinder
if (rangefinder_alt_ok()) { if (_copter.rangefinder_alt_ok()) {
// if rangefinder is ok, use surface tracking // if rangefinder is ok, use surface tracking
target_climb_rate = get_surface_tracking_climb_rate(target_climb_rate, pos_control->get_alt_target(), G_Dt); target_climb_rate = get_surface_tracking_climb_rate(target_climb_rate, pos_control->get_alt_target(), G_Dt);
} }
@ -543,7 +544,7 @@ void Copter::poshold_run()
} }
// poshold_update_pilot_lean_angle - update the pilot's filtered lean angle with the latest raw input received // poshold_update_pilot_lean_angle - update the pilot's filtered lean angle with the latest raw input received
void Copter::poshold_update_pilot_lean_angle(float &lean_angle_filtered, float &lean_angle_raw) void Copter::FlightMode_POSHOLD::poshold_update_pilot_lean_angle(float &lean_angle_filtered, float &lean_angle_raw)
{ {
// if raw input is large or reversing the vehicle's lean angle immediately set the fitlered angle to the new raw angle // if raw input is large or reversing the vehicle's lean angle immediately set the fitlered angle to the new raw angle
if ((lean_angle_filtered > 0 && lean_angle_raw < 0) || (lean_angle_filtered < 0 && lean_angle_raw > 0) || (fabsf(lean_angle_raw) > POSHOLD_STICK_RELEASE_SMOOTH_ANGLE)) { if ((lean_angle_filtered > 0 && lean_angle_raw < 0) || (lean_angle_filtered < 0 && lean_angle_raw > 0) || (fabsf(lean_angle_raw) > POSHOLD_STICK_RELEASE_SMOOTH_ANGLE)) {
@ -565,7 +566,7 @@ void Copter::poshold_update_pilot_lean_angle(float &lean_angle_filtered, float &
// poshold_mix_controls - mixes two controls based on the mix_ratio // poshold_mix_controls - mixes two controls based on the mix_ratio
// mix_ratio of 1 = use first_control completely, 0 = use second_control completely, 0.5 = mix evenly // mix_ratio of 1 = use first_control completely, 0 = use second_control completely, 0.5 = mix evenly
int16_t Copter::poshold_mix_controls(float mix_ratio, int16_t first_control, int16_t second_control) int16_t Copter::FlightMode_POSHOLD::poshold_mix_controls(float mix_ratio, int16_t first_control, int16_t second_control)
{ {
mix_ratio = constrain_float(mix_ratio, 0.0f, 1.0f); mix_ratio = constrain_float(mix_ratio, 0.0f, 1.0f);
return (int16_t)((mix_ratio * first_control) + ((1.0f-mix_ratio)*second_control)); return (int16_t)((mix_ratio * first_control) + ((1.0f-mix_ratio)*second_control));
@ -574,7 +575,7 @@ int16_t Copter::poshold_mix_controls(float mix_ratio, int16_t first_control, int
// poshold_update_brake_angle_from_velocity - updates the brake_angle based on the vehicle's velocity and brake_gain // poshold_update_brake_angle_from_velocity - updates the brake_angle based on the vehicle's velocity and brake_gain
// brake_angle is slewed with the wpnav.poshold_brake_rate and constrained by the wpnav.poshold_braking_angle_max // brake_angle is slewed with the wpnav.poshold_brake_rate and constrained by the wpnav.poshold_braking_angle_max
// velocity is assumed to be in the same direction as lean angle so for pitch you should provide the velocity backwards (i.e. -ve forward velocity) // velocity is assumed to be in the same direction as lean angle so for pitch you should provide the velocity backwards (i.e. -ve forward velocity)
void Copter::poshold_update_brake_angle_from_velocity(int16_t &brake_angle, float velocity) void Copter::FlightMode_POSHOLD::poshold_update_brake_angle_from_velocity(int16_t &brake_angle, float velocity)
{ {
float lean_angle; float lean_angle;
int16_t brake_rate = g.poshold_brake_rate; int16_t brake_rate = g.poshold_brake_rate;
@ -600,7 +601,7 @@ void Copter::poshold_update_brake_angle_from_velocity(int16_t &brake_angle, floa
// poshold_update_wind_comp_estimate - updates wind compensation estimate // poshold_update_wind_comp_estimate - updates wind compensation estimate
// should be called at the maximum loop rate when loiter is engaged // should be called at the maximum loop rate when loiter is engaged
void Copter::poshold_update_wind_comp_estimate() void Copter::FlightMode_POSHOLD::poshold_update_wind_comp_estimate()
{ {
// check wind estimate start has not been delayed // check wind estimate start has not been delayed
if (poshold.wind_comp_start_timer > 0) { if (poshold.wind_comp_start_timer > 0) {
@ -636,7 +637,7 @@ void Copter::poshold_update_wind_comp_estimate()
// poshold_get_wind_comp_lean_angles - retrieve wind compensation angles in body frame roll and pitch angles // poshold_get_wind_comp_lean_angles - retrieve wind compensation angles in body frame roll and pitch angles
// should be called at the maximum loop rate // should be called at the maximum loop rate
void Copter::poshold_get_wind_comp_lean_angles(int16_t &roll_angle, int16_t &pitch_angle) void Copter::FlightMode_POSHOLD::poshold_get_wind_comp_lean_angles(int16_t &roll_angle, int16_t &pitch_angle)
{ {
// reduce rate to 10hz // reduce rate to 10hz
poshold.wind_comp_timer++; poshold.wind_comp_timer++;
@ -651,7 +652,7 @@ void Copter::poshold_get_wind_comp_lean_angles(int16_t &roll_angle, int16_t &pit
} }
// poshold_roll_controller_to_pilot_override - initialises transition from a controller submode (brake or loiter) to a pilot override on roll axis // poshold_roll_controller_to_pilot_override - initialises transition from a controller submode (brake or loiter) to a pilot override on roll axis
void Copter::poshold_roll_controller_to_pilot_override() void Copter::FlightMode_POSHOLD::poshold_roll_controller_to_pilot_override()
{ {
poshold.roll_mode = POSHOLD_CONTROLLER_TO_PILOT_OVERRIDE; poshold.roll_mode = POSHOLD_CONTROLLER_TO_PILOT_OVERRIDE;
poshold.controller_to_pilot_timer_roll = POSHOLD_CONTROLLER_TO_PILOT_MIX_TIMER; poshold.controller_to_pilot_timer_roll = POSHOLD_CONTROLLER_TO_PILOT_MIX_TIMER;
@ -662,7 +663,7 @@ void Copter::poshold_roll_controller_to_pilot_override()
} }
// poshold_pitch_controller_to_pilot_override - initialises transition from a controller submode (brake or loiter) to a pilot override on roll axis // poshold_pitch_controller_to_pilot_override - initialises transition from a controller submode (brake or loiter) to a pilot override on roll axis
void Copter::poshold_pitch_controller_to_pilot_override() void Copter::FlightMode_POSHOLD::poshold_pitch_controller_to_pilot_override()
{ {
poshold.pitch_mode = POSHOLD_CONTROLLER_TO_PILOT_OVERRIDE; poshold.pitch_mode = POSHOLD_CONTROLLER_TO_PILOT_OVERRIDE;
poshold.controller_to_pilot_timer_pitch = POSHOLD_CONTROLLER_TO_PILOT_MIX_TIMER; poshold.controller_to_pilot_timer_pitch = POSHOLD_CONTROLLER_TO_PILOT_MIX_TIMER;

View File

@ -134,7 +134,10 @@ bool Copter::set_mode(control_mode_t mode, mode_reason_t reason)
#if POSHOLD_ENABLED == ENABLED #if POSHOLD_ENABLED == ENABLED
case POSHOLD: case POSHOLD:
success = poshold_init(ignore_checks); success = flightmode_poshold.init(ignore_checks);
if (success) {
flightmode = &flightmode_poshold;
}
break; break;
#endif #endif
@ -224,12 +227,6 @@ void Copter::update_flight_mode()
switch (control_mode) { switch (control_mode) {
#if POSHOLD_ENABLED == ENABLED
case POSHOLD:
poshold_run();
break;
#endif
case BRAKE: case BRAKE:
brake_run(); brake_run();
break; break;
@ -317,7 +314,6 @@ bool Copter::mode_requires_GPS()
} }
switch (control_mode) { switch (control_mode) {
case SMART_RTL: case SMART_RTL:
case POSHOLD:
case BRAKE: case BRAKE:
case AVOID_ADSB: case AVOID_ADSB:
case THROW: case THROW:
@ -378,9 +374,6 @@ void Copter::notify_flight_mode()
// set flight mode string // set flight mode string
switch (control_mode) { switch (control_mode) {
case POSHOLD:
notify.set_flight_mode_str("PHLD");
break;
case BRAKE: case BRAKE:
notify.set_flight_mode_str("BRAK"); notify.set_flight_mode_str("BRAK");
break; break;