CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
Ardupilot

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.

GitHub Repository: Ardupilot/ardupilot
Path: blob/master/ArduSub/Attitude.cpp
Views: 1798
1
#include "Sub.h"
2
3
// get_pilot_desired_angle - transform pilot's roll or pitch input into a desired lean angle
4
// returns desired angle in centi-degrees
5
void Sub::get_pilot_desired_lean_angles(float roll_in, float pitch_in, float &roll_out, float &pitch_out, float angle_max)
6
{
7
// sanity check angle max parameter
8
aparm.angle_max.set(constrain_int16(aparm.angle_max,1000,8000));
9
10
// limit max lean angle
11
angle_max = constrain_float(angle_max, 1000, aparm.angle_max);
12
13
// scale roll_in, pitch_in to ANGLE_MAX parameter range
14
float scaler = aparm.angle_max/(float)ROLL_PITCH_INPUT_MAX;
15
roll_in *= scaler;
16
pitch_in *= scaler;
17
18
// do circular limit
19
float total_in = norm(pitch_in, roll_in);
20
if (total_in > angle_max) {
21
float ratio = angle_max / total_in;
22
roll_in *= ratio;
23
pitch_in *= ratio;
24
}
25
26
// do lateral tilt to euler roll conversion
27
roll_in = (18000/M_PI) * atanf(cosf(pitch_in*(M_PI/18000))*tanf(roll_in*(M_PI/18000)));
28
29
// return
30
roll_out = roll_in;
31
pitch_out = pitch_in;
32
}
33
34
// get_pilot_desired_heading - transform pilot's yaw input into a
35
// desired yaw rate
36
// returns desired yaw rate in centi-degrees per second
37
float Sub::get_pilot_desired_yaw_rate(int16_t stick_angle) const
38
{
39
// convert pilot input to the desired yaw rate
40
return stick_angle * g.acro_yaw_p;
41
}
42
43
// check for ekf yaw reset and adjust target heading
44
void Sub::check_ekf_yaw_reset()
45
{
46
float yaw_angle_change_rad;
47
uint32_t new_ekfYawReset_ms = ahrs.getLastYawResetAngle(yaw_angle_change_rad);
48
if (new_ekfYawReset_ms != ekfYawReset_ms) {
49
attitude_control.inertial_frame_reset();
50
ekfYawReset_ms = new_ekfYawReset_ms;
51
}
52
}
53
54
/*************************************************************
55
* yaw controllers
56
*************************************************************/
57
58
// get_roi_yaw - returns heading towards location held in roi_WP
59
// should be called at 100hz
60
float Sub::get_roi_yaw()
61
{
62
static uint8_t roi_yaw_counter = 0; // used to reduce update rate to 100hz
63
64
roi_yaw_counter++;
65
if (roi_yaw_counter >= 4) {
66
roi_yaw_counter = 0;
67
yaw_look_at_WP_bearing = get_bearing_cd(inertial_nav.get_position_xy_cm(), roi_WP.xy());
68
}
69
70
return yaw_look_at_WP_bearing;
71
}
72
73
float Sub::get_look_ahead_yaw()
74
{
75
const Vector3f& vel = inertial_nav.get_velocity_neu_cms();
76
const float speed_sq = vel.xy().length_squared();
77
// Commanded Yaw to automatically look ahead.
78
if (position_ok() && (speed_sq > (YAW_LOOK_AHEAD_MIN_SPEED * YAW_LOOK_AHEAD_MIN_SPEED))) {
79
yaw_look_ahead_bearing = degrees(atan2f(vel.y,vel.x))*100.0f;
80
}
81
return yaw_look_ahead_bearing;
82
}
83
84
/*************************************************************
85
* throttle control
86
****************************************************************/
87
88
// get_pilot_desired_climb_rate - transform pilot's throttle input to climb rate in cm/s
89
// without any deadzone at the bottom
90
float Sub::get_pilot_desired_climb_rate(float throttle_control)
91
{
92
// throttle failsafe check
93
if (failsafe.pilot_input) {
94
return 0.0f;
95
}
96
97
float desired_rate = 0.0f;
98
float mid_stick = channel_throttle->get_control_mid();
99
float deadband_top = mid_stick + g.throttle_deadzone * gain;
100
float deadband_bottom = mid_stick - g.throttle_deadzone * gain;
101
102
// ensure a reasonable throttle value
103
throttle_control = constrain_float(throttle_control,0.0f,1000.0f);
104
105
// ensure a reasonable deadzone
106
g.throttle_deadzone.set(constrain_int16(g.throttle_deadzone, 0, 400));
107
108
// check throttle is above, below or in the deadband
109
if (throttle_control < deadband_bottom) {
110
// below the deadband
111
desired_rate = get_pilot_speed_dn() * (throttle_control-deadband_bottom) / deadband_bottom;
112
} else if (throttle_control > deadband_top) {
113
// above the deadband
114
desired_rate = g.pilot_speed_up * (throttle_control-deadband_top) / (1000.0f-deadband_top);
115
} else {
116
// must be in the deadband
117
desired_rate = 0.0f;
118
}
119
120
// desired climb rate for logging
121
desired_climb_rate = desired_rate;
122
123
return desired_rate;
124
}
125
126
// rotate vector from vehicle's perspective to North-East frame
127
void Sub::rotate_body_frame_to_NE(float &x, float &y)
128
{
129
float ne_x = x*ahrs.cos_yaw() - y*ahrs.sin_yaw();
130
float ne_y = x*ahrs.sin_yaw() + y*ahrs.cos_yaw();
131
x = ne_x;
132
y = ne_y;
133
}
134
135
// It will return the PILOT_SPEED_DN value if non zero, otherwise if zero it returns the PILOT_SPEED_UP value.
136
uint16_t Sub::get_pilot_speed_dn() const
137
{
138
if (g.pilot_speed_dn == 0) {
139
return abs(g.pilot_speed_up);
140
}
141
return abs(g.pilot_speed_dn);
142
}
143
144