4 bool ModeGuided::_enter()
6 plane
.guided_throttle_passthru
= false;
8 when entering guided mode we set the target as the current
9 location. This matches the behaviour of the copter code
11 Location loc
{plane
.current_loc
};
13 #if HAL_QUADPLANE_ENABLED
14 if (plane
.quadplane
.guided_mode_enabled()) {
16 if using Q_GUIDED_MODE then project forward by the stopping distance
18 loc
.offset_bearing(degrees(ahrs
.groundspeed_vector().angle()),
19 plane
.quadplane
.stopping_distance());
23 // set guided radius to WP_LOITER_RAD on mode change.
26 plane
.set_guided_WP(loc
);
30 void ModeGuided::update()
32 #if HAL_QUADPLANE_ENABLED
33 if (plane
.auto_state
.vtol_loiter
&& plane
.quadplane
.available()) {
34 plane
.quadplane
.guided_update();
39 // Received an external msg that guides roll in the last 3 seconds?
40 if (plane
.guided_state
.last_forced_rpy_ms
.x
> 0 &&
41 millis() - plane
.guided_state
.last_forced_rpy_ms
.x
< 3000) {
42 plane
.nav_roll_cd
= constrain_int32(plane
.guided_state
.forced_rpy_cd
.x
, -plane
.roll_limit_cd
, plane
.roll_limit_cd
);
43 plane
.update_load_factor();
45 #if OFFBOARD_GUIDED == ENABLED
46 // guided_state.target_heading is radians at this point between -pi and pi ( defaults to -4 )
47 // This function is used in Guided and AvoidADSB, check for guided
48 } else if ((plane
.control_mode
== &plane
.mode_guided
) && (plane
.guided_state
.target_heading_type
!= GUIDED_HEADING_NONE
) ) {
49 uint32_t tnow
= AP_HAL::millis();
50 float delta
= (tnow
- plane
.guided_state
.target_heading_time_ms
) * 1e-3f
;
51 plane
.guided_state
.target_heading_time_ms
= tnow
;
54 if (plane
.guided_state
.target_heading_type
== GUIDED_HEADING_HEADING
) {
55 error
= wrap_PI(plane
.guided_state
.target_heading
- AP::ahrs().get_yaw());
57 Vector2f groundspeed
= AP::ahrs().groundspeed_vector();
58 error
= wrap_PI(plane
.guided_state
.target_heading
- atan2f(-groundspeed
.y
, -groundspeed
.x
) + M_PI
);
61 float bank_limit
= degrees(atanf(plane
.guided_state
.target_heading_accel_limit
/GRAVITY_MSS
)) * 1e2f
;
62 bank_limit
= MIN(bank_limit
, plane
.roll_limit_cd
);
64 // push error into AC_PID
65 const float desired
= plane
.g2
.guidedHeading
.update_error(error
, delta
, plane
.guided_state
.target_heading_limit
);
67 // Check for output saturation
68 plane
.guided_state
.target_heading_limit
= fabsf(desired
) >= bank_limit
;
70 plane
.nav_roll_cd
= constrain_int32(desired
, -bank_limit
, bank_limit
);
71 plane
.update_load_factor();
73 #endif // OFFBOARD_GUIDED == ENABLED
75 plane
.calc_nav_roll();
78 if (plane
.guided_state
.last_forced_rpy_ms
.y
> 0 &&
79 millis() - plane
.guided_state
.last_forced_rpy_ms
.y
< 3000) {
80 plane
.nav_pitch_cd
= constrain_int32(plane
.guided_state
.forced_rpy_cd
.y
, plane
.pitch_limit_min
*100, plane
.aparm
.pitch_limit_max
.get()*100);
82 plane
.calc_nav_pitch();
86 if (plane
.guided_throttle_passthru
) {
87 // manual passthrough of throttle in fence breach
88 SRV_Channels::set_output_scaled(SRV_Channel::k_throttle
, plane
.get_throttle_input(true));
90 } else if (plane
.aparm
.throttle_cruise
> 1 &&
91 plane
.guided_state
.last_forced_throttle_ms
> 0 &&
92 millis() - plane
.guided_state
.last_forced_throttle_ms
< 3000) {
93 // Received an external msg that guides throttle in the last 3 seconds?
94 SRV_Channels::set_output_scaled(SRV_Channel::k_throttle
, plane
.guided_state
.forced_throttle
);
98 plane
.calc_throttle();
104 void ModeGuided::navigate()
106 plane
.update_loiter(active_radius_m
);
109 bool ModeGuided::handle_guided_request(Location target_loc
)
111 // add home alt if needed
112 if (target_loc
.relative_alt
) {
113 target_loc
.alt
+= plane
.home
.alt
;
114 target_loc
.relative_alt
= 0;
117 plane
.set_guided_WP(target_loc
);
122 void ModeGuided::set_radius_and_direction(const float radius
, const bool direction_is_ccw
)
124 // constrain to (uint16_t) range for update_loiter()
125 active_radius_m
= constrain_int32(fabsf(radius
), 0, UINT16_MAX
);
126 plane
.loiter
.direction
= direction_is_ccw
? -1 : 1;
129 void ModeGuided::update_target_altitude()
131 #if OFFBOARD_GUIDED == ENABLED
132 if (((plane
.guided_state
.target_alt_time_ms
!= 0) || plane
.guided_state
.target_alt
> -0.001 )) { // target_alt now defaults to -1, and _time_ms defaults to zero.
133 // offboard altitude demanded
134 uint32_t now
= AP_HAL::millis();
135 float delta
= 1e-3f
* (now
- plane
.guided_state
.target_alt_time_ms
);
136 plane
.guided_state
.target_alt_time_ms
= now
;
137 // determine delta accurately as a float
138 float delta_amt_f
= delta
* plane
.guided_state
.target_alt_accel
;
139 // then scale x100 to match last_target_alt and convert to a signed int32_t as it may be negative
140 int32_t delta_amt_i
= (int32_t)(100.0 * delta_amt_f
);
142 temp
.alt
= plane
.guided_state
.last_target_alt
+ delta_amt_i
; // ...to avoid floats here,
143 if (is_positive(plane
.guided_state
.target_alt_accel
)) {
144 temp
.alt
= MIN(plane
.guided_state
.target_alt
, temp
.alt
);
146 temp
.alt
= MAX(plane
.guided_state
.target_alt
, temp
.alt
);
148 plane
.guided_state
.last_target_alt
= temp
.alt
;
149 plane
.set_target_altitude_location(temp
);
151 #endif // OFFBOARD_GUIDED == ENABLED
153 Mode::update_target_altitude();