diff --git a/conf/airframes/tudelft/rotwing_v3c_oneloop.xml b/conf/airframes/tudelft/rotwing_v3c_oneloop.xml
index d85317f991..5493a7a510 100644
--- a/conf/airframes/tudelft/rotwing_v3c_oneloop.xml
+++ b/conf/airframes/tudelft/rotwing_v3c_oneloop.xml
@@ -120,8 +120,10 @@
+
+
diff --git a/conf/airframes/tudelft/rotwing_v3c_oneloop_optitrack.xml b/conf/airframes/tudelft/rotwing_v3c_oneloop_optitrack.xml
index dcccf58df7..34f0e4355a 100644
--- a/conf/airframes/tudelft/rotwing_v3c_oneloop_optitrack.xml
+++ b/conf/airframes/tudelft/rotwing_v3c_oneloop_optitrack.xml
@@ -120,9 +120,11 @@
+
-
+
+
diff --git a/conf/airframes/tudelft/rotwing_v3c_oneloop_optitrack_ext_pose.xml b/conf/airframes/tudelft/rotwing_v3c_oneloop_optitrack_ext_pose.xml
index 1753f9b3ab..c1aacf5397 100644
--- a/conf/airframes/tudelft/rotwing_v3c_oneloop_optitrack_ext_pose.xml
+++ b/conf/airframes/tudelft/rotwing_v3c_oneloop_optitrack_ext_pose.xml
@@ -112,9 +112,11 @@
+
-
+
+
diff --git a/conf/airframes/tudelft/rotwing_v3c_oneloop_simulation.xml b/conf/airframes/tudelft/rotwing_v3c_oneloop_simulation.xml
index 038927d614..e39060d373 100644
--- a/conf/airframes/tudelft/rotwing_v3c_oneloop_simulation.xml
+++ b/conf/airframes/tudelft/rotwing_v3c_oneloop_simulation.xml
@@ -81,8 +81,10 @@
+
+
diff --git a/conf/modules/nav_hybrid.xml b/conf/modules/nav_hybrid.xml
index b552ae9612..0db56ace5c 100644
--- a/conf/modules/nav_hybrid.xml
+++ b/conf/modules/nav_hybrid.xml
@@ -7,6 +7,9 @@
@@ -19,8 +22,9 @@
+
-
+
diff --git a/sw/airborne/modules/nav/nav_rotorcraft_hybrid.c b/sw/airborne/modules/nav/nav_rotorcraft_hybrid.c
index 6602645a47..b4a7e03ee9 100644
--- a/sw/airborne/modules/nav/nav_rotorcraft_hybrid.c
+++ b/sw/airborne/modules/nav/nav_rotorcraft_hybrid.c
@@ -51,13 +51,27 @@ float nav_max_speed = NAV_MAX_SPEED;
#define NAV_HYBRID_GOTO_MAX_SPEED NAV_MAX_SPEED
#endif
-float nav_goto_max_speed = NAV_HYBRID_GOTO_MAX_SPEED;
-
#ifndef NAV_HYBRID_MAX_DECELERATION
#define NAV_HYBRID_MAX_DECELERATION 1.0
#endif
-float nav_max_deceleration_sp = NAV_HYBRID_MAX_DECELERATION;
+#ifndef NAV_HYBRID_MAX_ACCELERATION
+#define NAV_HYBRID_MAX_ACCELERATION 4.0
+#endif
+
+#ifndef NAV_HYBRID_SOFT_ACCELERATION
+#define NAV_HYBRID_SOFT_ACCELERATION NAV_HYBRID_MAX_ACCELERATION
+#endif
+
+float nav_max_deceleration_sp = NAV_HYBRID_MAX_DECELERATION; //Maximum deceleration allowed for the set-point
+float nav_max_acceleration_sp = NAV_HYBRID_MAX_ACCELERATION; //Maximum acceleration allowed for the set-point
+float nav_hybrid_soft_acceleration = NAV_HYBRID_SOFT_ACCELERATION; //Soft acceleration limit allowed for the set-point (Equal to the maximum acceleration by default)
+float nav_hybrid_max_acceleration = NAV_HYBRID_MAX_ACCELERATION; //Maximum general limit in acceleration allowed for the hybrid navigation
+
+#ifndef NAV_HYBRID_MAX_EXPECTED_WIND
+#define NAV_HYBRID_MAX_EXPECTED_WIND 5.0f
+#endif
+float nav_hybrid_max_expected_wind = NAV_HYBRID_MAX_EXPECTED_WIND;
#ifdef NAV_HYBRID_LINE_GAIN
float nav_hybrid_line_gain = NAV_HYBRID_LINE_GAIN;
@@ -83,15 +97,21 @@ float nav_hybrid_pos_gain = 1.0f;
bool force_forward = 0.0f;
#endif
-#ifndef NAV_HYBRID_GOTO_MODE
-#define NAV_HYBRID_GOTO_MODE NAV_SETPOINT_MODE_SPEED
+/* When using external vision, run the nav functions in position mode for better tracking*/
+#ifndef NAV_HYBRID_EXT_VISION_SETPOINT_MODE
+#define NAV_HYBRID_EXT_VISION_SETPOINT_MODE FALSE
#endif
+/* Use max target groundspeed and max acceleration to limit circle radius*/
+#ifndef NAV_HYBRID_LIMIT_CIRCLE_RADIUS
+#define NAV_HYBRID_LIMIT_CIRCLE_RADIUS FALSE
+#endif
/** Implement basic nav function for the hybrid case
*/
static void nav_hybrid_goto(struct EnuCoor_f *wp)
{
+ nav_max_acceleration_sp = nav_hybrid_soft_acceleration;
nav_rotorcraft_base.goto_wp.to = *wp;
nav_rotorcraft_base.goto_wp.dist2_to_wp = get_dist2_to_point(wp);
VECT2_COPY(nav.target, *wp);
@@ -107,7 +127,7 @@ static void nav_hybrid_goto(struct EnuCoor_f *wp)
// Bound the setpoint velocity vector
float max_h_speed = nav_max_speed;
if (!force_forward) {
- // If not in force_forward, compute speed based on decceleration and nav_goto_max_speed
+ // If not in force_forward, compute speed based on deceleration and nav_max_speed
// Calculate distance to waypoint
float dist_to_wp = float_vect2_norm(&pos_error);
// Calculate max speed when decelerating at MAX capacity a_max
@@ -118,13 +138,19 @@ static void nav_hybrid_goto(struct EnuCoor_f *wp)
float max_speed_decel2 = fabsf(2.f * dist_to_wp * nav_max_deceleration_sp); // dist_to_wp can only be positive, but just in case
float max_speed_decel = sqrtf(max_speed_decel2);
// Bound the setpoint velocity vector
- max_h_speed = Min(nav_goto_max_speed, max_speed_decel); // use hover max speed
+ max_h_speed = Min(nav_max_speed, max_speed_decel);
}
float_vect2_bound_in_2d(&speed_sp, max_h_speed);
VECT2_COPY(nav.speed, speed_sp);
nav.horizontal_mode = NAV_HORIZONTAL_MODE_WAYPOINT;
- nav.setpoint_mode = NAV_HYBRID_GOTO_MODE;
+
+ // In optitrack tests use position mode for more precise hovering
+#if NAV_HYBRID_EXT_VISION_SETPOINT_MODE
+ nav.setpoint_mode = NAV_SETPOINT_MODE_POS;
+#else
+ nav.setpoint_mode = NAV_SETPOINT_MODE_SPEED;
+#endif
}
static void nav_hybrid_route(struct EnuCoor_f *wp_start, struct EnuCoor_f *wp_end)
@@ -225,7 +251,10 @@ static void nav_hybrid_circle(struct EnuCoor_f *wp_center, float radius)
float sign_radius = radius > 0.f ? 1.f : -1.f;
// absolute radius
float abs_radius = fabsf(radius);
-
+#if NAV_HYBRID_LIMIT_CIRCLE_RADIUS
+ float min_radius = pow(nav_max_speed+nav_hybrid_max_expected_wind,2) / (nav_hybrid_max_acceleration * 0.8);
+ abs_radius = Max(abs_radius, min_radius);
+#endif
if (abs_radius > 0.1f) {
// store last qdr
float last_qdr = nav_rotorcraft_base.circle.qdr;
@@ -248,20 +277,22 @@ static void nav_hybrid_circle(struct EnuCoor_f *wp_center, float radius)
VECT2_COPY(nav.target, *wp_center);
}
// compute desired speed
+ float radius_diff = fabsf(float_vect2_norm(&pos_diff) - abs_radius);
+ if (radius_diff > NAV_HYBRID_NAV_CIRCLE_DIST) {
+ // far from circle, speed proportional to diff
+ desired_speed = radius_diff * nav_hybrid_pos_gain;
+ nav_max_acceleration_sp = nav_hybrid_soft_acceleration;
+ } else {
+ // close to circle, speed function of radius for a feasible turn
+ // 0.8 * MAX_BANK gives some margins for the turns
+ desired_speed = sqrtf(PPRZ_ISA_GRAVITY * abs_radius * tanf(0.8f * nav_hybrid_max_bank));
+ nav_max_acceleration_sp = nav_hybrid_max_acceleration ;
+ }
if (force_forward) {
desired_speed = nav_max_speed;
- } else {
- float radius_diff = fabsf(float_vect2_norm(&pos_diff) - abs_radius);
- if (radius_diff > NAV_HYBRID_NAV_CIRCLE_DIST) {
- // far from circle, speed proportional to diff
- desired_speed = radius_diff * nav_hybrid_pos_gain;
- } else {
- // close to circle, speed function of radius for a feasible turn
- // 0.8 * MAX_BANK gives some margins for the turns
- desired_speed = sqrtf(PPRZ_ISA_GRAVITY * abs_radius * tanf(0.8f * nav_hybrid_max_bank));
- }
- Bound(desired_speed, 0.0f, nav_max_speed);
+ nav_max_acceleration_sp = nav_hybrid_max_acceleration ;
}
+ Bound(desired_speed, 0.0f, nav_max_speed);
// compute speed vector from target position
struct FloatVect2 speed_unit;
VECT2_DIFF(speed_unit, nav.target, *stateGetPositionEnu_f());
@@ -269,7 +300,7 @@ static void nav_hybrid_circle(struct EnuCoor_f *wp_center, float radius)
VECT2_SMUL(nav.speed, speed_unit, desired_speed);
nav_rotorcraft_base.circle.center = *wp_center;
- nav_rotorcraft_base.circle.radius = radius;
+ nav_rotorcraft_base.circle.radius = sign_radius * abs_radius;
nav.horizontal_mode = NAV_HORIZONTAL_MODE_CIRCLE;
nav.setpoint_mode = NAV_SETPOINT_MODE_SPEED;
}
diff --git a/sw/airborne/modules/nav/nav_rotorcraft_hybrid.h b/sw/airborne/modules/nav/nav_rotorcraft_hybrid.h
index 39858cc990..c7a8343c12 100644
--- a/sw/airborne/modules/nav/nav_rotorcraft_hybrid.h
+++ b/sw/airborne/modules/nav/nav_rotorcraft_hybrid.h
@@ -33,16 +33,17 @@
// settings
extern float nav_max_speed; // max speed in route mode
-extern float nav_goto_max_speed; // max speed in goto/stay mode
extern float nav_max_deceleration_sp;
+extern float nav_max_acceleration_sp; // Maximum limit that can vary depending on the function
+extern float nav_hybrid_max_acceleration; // General setting
extern float nav_hybrid_line_gain;
extern float nav_hybrid_pos_gain;
extern float nav_hybrid_max_bank;
+extern float nav_hybrid_max_expected_wind;
#ifndef GUIDANCE_INDI_HYBRID
extern bool force_forward;
#endif
-
extern void nav_rotorcraft_hybrid_init(void);
#endif
diff --git a/sw/airborne/modules/rotwing_drone/rotwing_state.c b/sw/airborne/modules/rotwing_drone/rotwing_state.c
index 22ecef0bdd..ed3032d796 100644
--- a/sw/airborne/modules/rotwing_drone/rotwing_state.c
+++ b/sw/airborne/modules/rotwing_drone/rotwing_state.c
@@ -552,7 +552,6 @@ void rotwing_state_set_state_settings(void)
force_forward = rotwing_state_settings.force_forward;
nav_max_speed = rotwing_state_settings.nav_max_speed;
- nav_goto_max_speed = rotwing_state_settings.nav_max_speed;
// TO DO: pitch angle now hard coded scheduled by wing angle
diff --git a/sw/airborne/modules/rotwing_drone/rotwing_state_V2.c b/sw/airborne/modules/rotwing_drone/rotwing_state_V2.c
index 953bc65dfa..90b6d555f8 100644
--- a/sw/airborne/modules/rotwing_drone/rotwing_state_V2.c
+++ b/sw/airborne/modules/rotwing_drone/rotwing_state_V2.c
@@ -603,7 +603,6 @@ void rotwing_state_set_state_settings(void)
force_forward = rotwing_state_settings.force_forward;
nav_max_speed = rotwing_state_settings.nav_max_speed;
- nav_goto_max_speed = rotwing_state_settings.nav_max_speed;
// TO DO: pitch angle now hard coded scheduled by wing angle