Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Copter: guided mode update to use PosControl tools #17539

Merged
merged 34 commits into from Jul 10, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
745dd86
Copter: support for acceleration-based AttitudeControl
lthall May 11, 2021
f16b6dd
AC_AttitudeControl: AC_PosControl: Change input_pos_xyz name
lthall May 31, 2021
1b506b9
AC_AttitudeControl: AC_PosControl: Support Accel only input
lthall Jun 20, 2021
a83b356
AC_Math: Control: Support Accel only input
lthall Jun 20, 2021
4e3aecd
Tools: Autotest update guided bitbask to include acceleration
lthall Jun 22, 2021
f1c69fc
Sub: adjust for AttitudeControl library changes
lthall Jun 23, 2021
f071bd2
AC_WPNav: move code to generate terrain following kinematic path
lthall Jun 23, 2021
bdc37a2
AC_WPNav: get_terrain_offset and get_vector_NEU made public
rmackay9 Jun 26, 2021
0e7c085
Copter: guided accepts terrain alt position targets
rmackay9 Jun 26, 2021
9840279
AC_AttitudeControl: Add terain following to guided
lthall Jun 26, 2021
df13f6b
Copter: Guided prevent takeoff without takeoff command.
lthall Jul 8, 2021
c7ef92e
Copter: Guided: use common initialisation
lthall Jul 8, 2021
7844d82
AC_AttitudeControl: AC_PosControl: seperate kinimatic shaping from pi…
lthall Jul 8, 2021
d408c79
AC_WPNav: seperate kinimatic shaping from pid limit setting
lthall Jul 8, 2021
7f9195a
Sub: seperate kinimatic shaping from pid limit setting
lthall Jul 8, 2021
dd4827f
Plane: seperate kinimatic shaping from pid limit setting
lthall Jul 8, 2021
9d50313
Copter: seperate kinimatic shaping from pid limit setting
lthall Jul 8, 2021
2a83f49
Copter: Guided close gap between TARGET_LOCAL_NED and TARGET_GLOBAL_INT
lthall Jul 8, 2021
7c1f843
Copter: Guided: fix waypoint track reporting
lthall Jul 8, 2021
415a950
AC_AttitudeControl: AC_PosControl: support terrain following
lthall Jul 8, 2021
12505cf
Copter: Guided: support terrain following
lthall Jul 8, 2021
9e6ac67
Copter: Guided add terrain failsafe
lthall Jul 9, 2021
5e163f7
Copter: Guided: make aircraft stop on accel time out
lthall Jul 9, 2021
6d4b59b
Copter: Guided: stop aircraft if an invalid command is sent
lthall Jul 9, 2021
7082b21
Copter: Guided: use default yaw mode for all gps based sub modes.
lthall Jul 9, 2021
6034d6a
AC_AttitudeControl: AC_PosControl: support accel only input in the ve…
lthall Jul 9, 2021
31780fd
AC_AttitudeControl: Add accessor for yaw slew limit
lthall Jul 9, 2021
c9fa1c6
Copter: additional yaw modes and fixes
lthall Jul 9, 2021
008b4fe
AC_WPNav: Remove unused function
lthall Jul 9, 2021
da71d49
Copter: Guided Angle init Z controller on time out
lthall Jul 10, 2021
3b203c9
Copter: Auto Yaw variable names and comments
lthall Jul 10, 2021
a52fece
Copter: Guided: move to zero velocity after takeoff
lthall Jul 10, 2021
ea50cc0
Copter: add GUID_TIMEOUT for guided mode vel, accel and angle control
rmackay9 Jul 9, 2021
974d136
Copter: add TERRAIN_MARGIN parameter
rmackay9 Jul 9, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion ArduCopter/Copter.h
Expand Up @@ -791,7 +791,7 @@ class Copter : public AP_Vehicle {
#if FRAME_CONFIG == HELI_FRAME
void Log_Write_Heli(void);
#endif
void Log_Write_GuidedTarget(ModeGuided::SubMode submode, const Vector3f& pos_target, const Vector3f& vel_target);
void Log_Write_GuidedTarget(ModeGuided::SubMode submode, const Vector3f& pos_target, bool terrain_alt, const Vector3f& vel_target, const Vector3f& accel_target);
void Log_Write_SysID_Setup(uint8_t systemID_axis, float waveform_magnitude, float frequency_start, float frequency_stop, float time_fade_in, float time_const_freq, float time_record, float time_fade_out);
void Log_Write_SysID_Data(float waveform_time, float waveform_sample, float waveform_freq, float angle_x, float angle_y, float angle_z, float accel_x, float accel_y, float accel_z);
void Log_Write_Vehicle_Startup_Messages();
Expand Down Expand Up @@ -884,6 +884,7 @@ class Copter : public AP_Vehicle {
// terrain.cpp
void terrain_update();
void terrain_logging();
float get_terrain_margin() const;

// tuning.cpp
void tuning();
Expand Down
130 changes: 85 additions & 45 deletions ArduCopter/GCS_Mavlink.cpp
Expand Up @@ -119,30 +119,37 @@ void GCS_MAVLINK_Copter::send_position_target_local_ned()
const ModeGuided::SubMode guided_mode = copter.mode_guided.submode();
Vector3f target_pos;
Vector3f target_vel;
Vector3f target_accel;
uint16_t type_mask = 0;

switch (guided_mode) {
case ModeGuided::SubMode::Angle:
// we don't have a local target when in angle mode
return;
case ModeGuided::SubMode::TakeOff:
case ModeGuided::SubMode::WP:
type_mask = POSITION_TARGET_TYPEMASK_VX_IGNORE | POSITION_TARGET_TYPEMASK_VY_IGNORE | POSITION_TARGET_TYPEMASK_VZ_IGNORE |
POSITION_TARGET_TYPEMASK_AX_IGNORE | POSITION_TARGET_TYPEMASK_AY_IGNORE | POSITION_TARGET_TYPEMASK_AZ_IGNORE |
POSITION_TARGET_TYPEMASK_FORCE_SET | POSITION_TARGET_TYPEMASK_YAW_IGNORE| POSITION_TARGET_TYPEMASK_YAW_RATE_IGNORE; // ignore everything except position
target_pos = copter.wp_nav->get_wp_destination() * 0.01f; // convert to metres
target_pos = copter.mode_guided.get_target_pos().tofloat() * 0.01; // convert to metres
break;
case ModeGuided::SubMode::PosVelAccel:
type_mask = POSITION_TARGET_TYPEMASK_FORCE_SET | POSITION_TARGET_TYPEMASK_YAW_IGNORE| POSITION_TARGET_TYPEMASK_YAW_RATE_IGNORE; // ignore everything except position, velocity & acceleration
target_pos = copter.mode_guided.get_target_pos().tofloat() * 0.01; // convert to metres
target_vel = copter.mode_guided.get_target_vel() * 0.01f; // convert to metres/s
target_accel = copter.mode_guided.get_target_accel() * 0.01f; // convert to metres/s/s
break;
case ModeGuided::SubMode::Velocity:
case ModeGuided::SubMode::VelAccel:
type_mask = POSITION_TARGET_TYPEMASK_X_IGNORE | POSITION_TARGET_TYPEMASK_Y_IGNORE | POSITION_TARGET_TYPEMASK_Z_IGNORE |
POSITION_TARGET_TYPEMASK_AX_IGNORE | POSITION_TARGET_TYPEMASK_AY_IGNORE | POSITION_TARGET_TYPEMASK_AZ_IGNORE |
POSITION_TARGET_TYPEMASK_FORCE_SET | POSITION_TARGET_TYPEMASK_YAW_IGNORE| POSITION_TARGET_TYPEMASK_YAW_RATE_IGNORE; // ignore everything except velocity
target_vel = copter.flightmode->get_vel_desired_cms() * 0.01f; // convert to m/s
POSITION_TARGET_TYPEMASK_FORCE_SET | POSITION_TARGET_TYPEMASK_YAW_IGNORE| POSITION_TARGET_TYPEMASK_YAW_RATE_IGNORE; // ignore everything except velocity & acceleration
target_vel = copter.mode_guided.get_target_vel() * 0.01f; // convert to metres/s
target_accel = copter.mode_guided.get_target_accel() * 0.01f; // convert to metres/s/s
break;
case ModeGuided::SubMode::TakeOff:
case ModeGuided::SubMode::PosVel:
type_mask = POSITION_TARGET_TYPEMASK_AX_IGNORE | POSITION_TARGET_TYPEMASK_AY_IGNORE | POSITION_TARGET_TYPEMASK_AZ_IGNORE |
POSITION_TARGET_TYPEMASK_FORCE_SET | POSITION_TARGET_TYPEMASK_YAW_IGNORE| POSITION_TARGET_TYPEMASK_YAW_RATE_IGNORE; // ignore everything except position & velocity
target_pos = copter.wp_nav->get_wp_destination() * 0.01f;
target_vel = copter.flightmode->get_vel_desired_cms() * 0.01f;
case ModeGuided::SubMode::Accel:
type_mask = POSITION_TARGET_TYPEMASK_X_IGNORE | POSITION_TARGET_TYPEMASK_Y_IGNORE | POSITION_TARGET_TYPEMASK_Z_IGNORE |
POSITION_TARGET_TYPEMASK_VX_IGNORE | POSITION_TARGET_TYPEMASK_VY_IGNORE | POSITION_TARGET_TYPEMASK_VZ_IGNORE |
POSITION_TARGET_TYPEMASK_FORCE_SET | POSITION_TARGET_TYPEMASK_YAW_IGNORE| POSITION_TARGET_TYPEMASK_YAW_RATE_IGNORE; // ignore everything except velocity & acceleration
target_accel = copter.mode_guided.get_target_accel() * 0.01f; // convert to metres/s/s
break;
}

Expand All @@ -151,15 +158,15 @@ void GCS_MAVLINK_Copter::send_position_target_local_ned()
AP_HAL::millis(), // time boot ms
MAV_FRAME_LOCAL_NED,
type_mask,
target_pos.x, // x in metres
target_pos.y, // y in metres
-target_pos.z, // z in metres NED frame
target_vel.x, // vx in m/s
target_vel.y, // vy in m/s
-target_vel.z, // vz in m/s NED frame
0.0f, // afx
0.0f, // afy
0.0f, // afz
target_pos.x, // x in metres
target_pos.y, // y in metres
-target_pos.z, // z in metres NED frame
target_vel.x, // vx in m/s
target_vel.y, // vy in m/s
-target_vel.z, // vz in m/s NED frame
target_accel.x, // afx in m/s/s
target_accel.y, // afy in m/s/s
-target_accel.z,// afz in m/s/s NED frame
0.0f, // yaw
0.0f); // yaw_rate
#endif
Expand Down Expand Up @@ -697,11 +704,9 @@ MAV_RESULT GCS_MAVLINK_Copter::handle_command_mount(const mavlink_command_long_t
// if vehicle has a camera mount but it doesn't do pan control then yaw the entire vehicle instead
if ((copter.camera_mount.get_mount_type() != copter.camera_mount.MountType::Mount_Type_None) &&
!copter.camera_mount.has_pan_control()) {
copter.flightmode->auto_yaw.set_fixed_yaw(
copter.flightmode->auto_yaw.set_yaw_angle_rate(
(float)packet.param3 * 0.01f,
0.0f,
0,
false);
0.0f);
}
break;
#endif
Expand Down Expand Up @@ -967,11 +972,9 @@ void GCS_MAVLINK_Copter::handle_mount_message(const mavlink_message_t &msg)
// if vehicle has a camera mount but it doesn't do pan control then yaw the entire vehicle instead
if ((copter.camera_mount.get_mount_type() != copter.camera_mount.MountType::Mount_Type_None) &&
!copter.camera_mount.has_pan_control()) {
copter.flightmode->auto_yaw.set_fixed_yaw(
copter.flightmode->auto_yaw.set_yaw_angle_rate(
mavlink_msg_mount_control_get_input_c(&msg) * 0.01f,
0.0f,
0,
false);
0.0f);

break;
}
Expand Down Expand Up @@ -1102,6 +1105,8 @@ void GCS_MAVLINK_Copter::handleMessage(const mavlink_message_t &msg)
packet.coordinate_frame != MAV_FRAME_LOCAL_OFFSET_NED &&
packet.coordinate_frame != MAV_FRAME_BODY_NED &&
packet.coordinate_frame != MAV_FRAME_BODY_OFFSET_NED) {
// input is not valid so stop
copter.mode_guided.init(true);
break;
}

Expand All @@ -1111,11 +1116,6 @@ void GCS_MAVLINK_Copter::handleMessage(const mavlink_message_t &msg)
bool yaw_ignore = packet.type_mask & MAVLINK_SET_POS_TYPE_MASK_YAW_IGNORE;
bool yaw_rate_ignore = packet.type_mask & MAVLINK_SET_POS_TYPE_MASK_YAW_RATE_IGNORE;

// exit immediately if acceleration provided
if (!acc_ignore) {
break;
}

// prepare position
Vector3f pos_vector;
if (!pos_ignore) {
Expand Down Expand Up @@ -1145,6 +1145,17 @@ void GCS_MAVLINK_Copter::handleMessage(const mavlink_message_t &msg)
}
}

// prepare acceleration
Vector3f accel_vector;
if (!acc_ignore) {
// convert to cm
accel_vector = Vector3f(packet.afx * 100.0f, packet.afy * 100.0f, -packet.afz * 100.0f);
// rotate to body-frame if necessary
if (packet.coordinate_frame == MAV_FRAME_BODY_NED || packet.coordinate_frame == MAV_FRAME_BODY_OFFSET_NED) {
copter.rotate_body_frame_to_NE(accel_vector.x, accel_vector.y);
}
}

// prepare yaw
float yaw_cd = 0.0f;
bool yaw_relative = false;
Expand All @@ -1159,11 +1170,16 @@ void GCS_MAVLINK_Copter::handleMessage(const mavlink_message_t &msg)

// send request
if (!pos_ignore && !vel_ignore) {
copter.mode_guided.set_destination_posvel(pos_vector, vel_vector, !yaw_ignore, yaw_cd, !yaw_rate_ignore, yaw_rate_cds, yaw_relative);
copter.mode_guided.set_destination_posvelaccel(pos_vector, vel_vector, accel_vector, !yaw_ignore, yaw_cd, !yaw_rate_ignore, yaw_rate_cds, yaw_relative);
} else if (pos_ignore && !vel_ignore) {
copter.mode_guided.set_velocity(vel_vector, !yaw_ignore, yaw_cd, !yaw_rate_ignore, yaw_rate_cds, yaw_relative);
} else if (!pos_ignore && vel_ignore) {
copter.mode_guided.set_destination(pos_vector, !yaw_ignore, yaw_cd, !yaw_rate_ignore, yaw_rate_cds, yaw_relative);
copter.mode_guided.set_velaccel(vel_vector, accel_vector, !yaw_ignore, yaw_cd, !yaw_rate_ignore, yaw_rate_cds, yaw_relative);
} else if (pos_ignore && vel_ignore && !acc_ignore) {
copter.mode_guided.set_accel(accel_vector, !yaw_ignore, yaw_cd, !yaw_rate_ignore, yaw_rate_cds, yaw_relative);
} else if (!pos_ignore && vel_ignore && acc_ignore) {
lthall marked this conversation as resolved.
Show resolved Hide resolved
copter.mode_guided.set_destination(pos_vector, !yaw_ignore, yaw_cd, !yaw_rate_ignore, yaw_rate_cds, yaw_relative, false);
} else {
// input is not valid so stop
copter.mode_guided.init(true);
}

break;
Expand All @@ -1180,32 +1196,47 @@ void GCS_MAVLINK_Copter::handleMessage(const mavlink_message_t &msg)
break;
}

// todo: do we need to check for supported coordinate frames

bool pos_ignore = packet.type_mask & MAVLINK_SET_POS_TYPE_MASK_POS_IGNORE;
bool vel_ignore = packet.type_mask & MAVLINK_SET_POS_TYPE_MASK_VEL_IGNORE;
bool acc_ignore = packet.type_mask & MAVLINK_SET_POS_TYPE_MASK_ACC_IGNORE;
bool yaw_ignore = packet.type_mask & MAVLINK_SET_POS_TYPE_MASK_YAW_IGNORE;
bool yaw_rate_ignore = packet.type_mask & MAVLINK_SET_POS_TYPE_MASK_YAW_RATE_IGNORE;

// exit immediately if acceleration provided
if (!acc_ignore) {
break;
}

// extract location from message
Location loc;
if (!pos_ignore) {
// sanity check location
if (!check_latlng(packet.lat_int, packet.lon_int)) {
// input is not valid so stop
copter.mode_guided.init(true);
break;
}
Location::AltFrame frame;
if (!mavlink_coordinate_frame_to_location_alt_frame((MAV_FRAME)packet.coordinate_frame, frame)) {
// unknown coordinate frame
// input is not valid so stop
copter.mode_guided.init(true);
break;
}
loc = {packet.lat_int, packet.lon_int, int32_t(packet.alt*100), frame};
}

// prepare velocity
Vector3f vel_vector;
if (!vel_ignore) {
// convert to cm
vel_vector = Vector3f(packet.vx * 100.0f, packet.vy * 100.0f, -packet.vz * 100.0f);
}

// prepare acceleration
Vector3f accel_vector;
if (!acc_ignore) {
// convert to cm
accel_vector = Vector3f(packet.afx * 100.0f, packet.afy * 100.0f, -packet.afz * 100.0f);
}

// prepare yaw
float yaw_cd = 0.0f;
bool yaw_relative = false;
Expand All @@ -1223,17 +1254,26 @@ void GCS_MAVLINK_Copter::handleMessage(const mavlink_message_t &msg)
// convert Location to vector from ekf origin for posvel controller
if (loc.get_alt_frame() == Location::AltFrame::ABOVE_TERRAIN) {
// posvel controller does not support alt-above-terrain
// input is not valid so stop
copter.mode_guided.init(true);
break;
}
Vector3f pos_neu_cm;
if (!loc.get_vector_from_origin_NEU(pos_neu_cm)) {
// input is not valid so stop
copter.mode_guided.init(true);
break;
}
copter.mode_guided.set_destination_posvel(pos_neu_cm, Vector3f(packet.vx * 100.0f, packet.vy * 100.0f, -packet.vz * 100.0f), !yaw_ignore, yaw_cd, !yaw_rate_ignore, yaw_rate_cds, yaw_relative);
copter.mode_guided.set_destination_posvel(pos_neu_cm, vel_vector, !yaw_ignore, yaw_cd, !yaw_rate_ignore, yaw_rate_cds, yaw_relative);
} else if (pos_ignore && !vel_ignore) {
copter.mode_guided.set_velocity(Vector3f(packet.vx * 100.0f, packet.vy * 100.0f, -packet.vz * 100.0f), !yaw_ignore, yaw_cd, !yaw_rate_ignore, yaw_rate_cds, yaw_relative);
} else if (!pos_ignore && vel_ignore) {
copter.mode_guided.set_velaccel(vel_vector, accel_vector, !yaw_ignore, yaw_cd, !yaw_rate_ignore, yaw_rate_cds, yaw_relative);
} else if (pos_ignore && vel_ignore && !acc_ignore) {
copter.mode_guided.set_accel(accel_vector, !yaw_ignore, yaw_cd, !yaw_rate_ignore, yaw_rate_cds, yaw_relative);
} else if (!pos_ignore && vel_ignore && acc_ignore) {
copter.mode_guided.set_destination(loc, !yaw_ignore, yaw_cd, !yaw_rate_ignore, yaw_rate_cds, yaw_relative);
} else {
// input is not valid so stop
copter.mode_guided.init(true);
}

break;
Expand Down
21 changes: 17 additions & 4 deletions ArduCopter/Log.cpp
Expand Up @@ -374,15 +374,20 @@ struct PACKED log_GuidedTarget {
float pos_target_x;
float pos_target_y;
float pos_target_z;
uint8_t terrain;
float vel_target_x;
float vel_target_y;
float vel_target_z;
float accel_target_x;
float accel_target_y;
float accel_target_z;
};

// Write a Guided mode target
// pos_target is lat, lon, alt OR offset from ekf origin in cm OR roll, pitch, yaw target in centi-degrees
// terrain should be 0 if pos_target.z is alt-above-ekf-origin, 1 if alt-above-terrain
// vel_target is cm/s
void Copter::Log_Write_GuidedTarget(ModeGuided::SubMode target_type, const Vector3f& pos_target, const Vector3f& vel_target)
void Copter::Log_Write_GuidedTarget(ModeGuided::SubMode target_type, const Vector3f& pos_target, bool terrain_alt, const Vector3f& vel_target, const Vector3f& accel_target)
{
struct log_GuidedTarget pkt = {
LOG_PACKET_HEADER_INIT(LOG_GUIDEDTARGET_MSG),
Expand All @@ -391,9 +396,13 @@ void Copter::Log_Write_GuidedTarget(ModeGuided::SubMode target_type, const Vecto
pos_target_x : pos_target.x,
pos_target_y : pos_target.y,
pos_target_z : pos_target.z,
terrain : terrain_alt,
vel_target_x : vel_target.x,
vel_target_y : vel_target.y,
vel_target_z : vel_target.z
vel_target_z : vel_target.z,
accel_target_x : accel_target.x,
accel_target_y : accel_target.y,
accel_target_z : accel_target.z
};
logger.WriteBlock(&pkt, sizeof(pkt));
}
Expand Down Expand Up @@ -536,12 +545,16 @@ const struct LogStructure Copter::log_structure[] = {
// @Field: pX: Target position, X-Axis
// @Field: pY: Target position, Y-Axis
// @Field: pZ: Target position, Z-Axis
// @Field: Terrain: Target position, Z-Axis is alt above terrain
// @Field: vX: Target velocity, X-Axis
// @Field: vY: Target velocity, Y-Axis
// @Field: vZ: Target velocity, Z-Axis
// @Field: aX: Target acceleration, X-Axis
// @Field: aY: Target acceleration, Y-Axis
// @Field: aZ: Target acceleration, Z-Axis

{ LOG_GUIDEDTARGET_MSG, sizeof(log_GuidedTarget),
"GUID", "QBffffff", "TimeUS,Type,pX,pY,pZ,vX,vY,vZ", "s-mmmnnn", "F-BBBBBB" },
"GUID", "QBfffbffffff", "TimeUS,Type,pX,pY,pZ,Terrain,vX,vY,vZ,aX,aY,aZ", "s-mmm-nnnooo", "F-BBB-BBBBBB" },
};

void Copter::Log_Write_Vehicle_Startup_Messages()
Expand Down Expand Up @@ -573,7 +586,7 @@ void Copter::Log_Write_Data(LogDataID id, uint16_t value) {}
void Copter::Log_Write_Data(LogDataID id, float value) {}
void Copter::Log_Write_Parameter_Tuning(uint8_t param, float tuning_val, float tune_min, float tune_max) {}
void Copter::Log_Sensor_Health() {}
void Copter::Log_Write_GuidedTarget(ModeGuided::SubMode target_type, const Vector3f& pos_target, const Vector3f& vel_target) {}
void Copter::Log_Write_GuidedTarget(ModeGuided::SubMode target_type, const Vector3f& pos_target, bool terrain_alt, const Vector3f& vel_target, const Vector3f& accel_target) {}
void Copter::Log_Write_SysID_Setup(uint8_t systemID_axis, float waveform_magnitude, float frequency_start, float frequency_stop, float time_fade_in, float time_const_freq, float time_record, float time_fade_out) {}
void Copter::Log_Write_SysID_Data(float waveform_time, float waveform_sample, float waveform_freq, float angle_x, float angle_y, float angle_z, float accel_x, float accel_y, float accel_z) {}
void Copter::Log_Write_Vehicle_Startup_Messages() {}
Expand Down
22 changes: 21 additions & 1 deletion ArduCopter/Parameters.cpp
Expand Up @@ -1027,7 +1027,7 @@ const AP_Param::GroupInfo ParametersG2::var_info[] = {
// @Param: GUID_OPTIONS
// @DisplayName: Guided mode options
// @Description: Options that can be applied to change guided mode behaviour
// @Bitmask: 0:Allow Arming from Transmitter,2:Ignore pilot yaw,3:SetAttitudeTarget_ThrustAsThrust
// @Bitmask: 0:Allow Arming from Transmitter,2:Ignore pilot yaw,3:SetAttitudeTarget_ThrustAsThrust,4:DoNotStabilizePositionXY,5:DoNotStabilizeVelocityXY
// @User: Advanced
AP_GROUPINFO("GUID_OPTIONS", 41, ParametersG2, guided_options, 0),
#endif
Expand Down Expand Up @@ -1069,6 +1069,26 @@ const AP_Param::GroupInfo ParametersG2::var_info[] = {
AP_GROUPINFO("RNGFND_FILT", 45, ParametersG2, rangefinder_filt, RANGEFINDER_FILT_DEFAULT),
#endif

#if MODE_GUIDED_ENABLED == ENABLED
// @Param: GUID_TIMEOUT
// @DisplayName: Guided mode timeout
// @Description: Guided mode timeout after which vehicle will stop or return to level if no updates are received from caller. Only applicable during velocity, acceleration or angle control
// @Units: s
// @Range: 0.1 5
// @User: Advanced
AP_GROUPINFO("GUID_TIMEOUT", 46, ParametersG2, guided_timeout, 3.0),
#endif

#if AP_TERRAIN_AVAILABLE && AC_TERRAIN
// @Param: TERRAIN_MARGIN
// @DisplayName: Terrain following altitude margin
// @Description: Terrain following altitude margin. Vehicle will stop if distance from target altitude is larger than this margin (in meters)
// @Units: m
// @Range: 0.1 100
// @User: Advanced
AP_GROUPINFO("TERRAIN_MARGIN", 47, ParametersG2, terrain_margin, 10.0),
#endif

AP_GROUPEND
};

Expand Down
7 changes: 7 additions & 0 deletions ArduCopter/Parameters.h
Expand Up @@ -649,6 +649,13 @@ class ParametersG2 {
AP_Float rangefinder_filt;
#endif

#if MODE_GUIDED_ENABLED == ENABLED
AP_Float guided_timeout;
#endif

#if AP_TERRAIN_AVAILABLE && AC_TERRAIN
AP_Float terrain_margin;
#endif
};

extern const AP_Param::Info var_info[];