Paparazzi UAS v7.0_unstable
Paparazzi is a free software Unmanned Aircraft System.
Loading...
Searching...
No Matches
nps_fdm_rover.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2021 Jesús Bautista <jesusbautistavillar@gmail.com>
3 * Hector García <noeth3r@gmail.com>
4 *
5 * This file is part of paparazzi.
6 *
7 * paparazzi is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2, or (at your option)
10 * any later version.
11 *
12 * paparazzi is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with paparazzi; see the file COPYING. If not, see
19 * <http://www.gnu.org/licenses/>.
20 */
21
22#include "nps_fdm.h"
23
24#include <stdlib.h>
25#include <stdio.h>
26
27#include "std.h"
28#include "math/pprz_geodetic.h"
31#include "math/pprz_algebra.h"
33#include "math/pprz_isa.h"
34
35#include "generated/airframe.h"
36#include "generated/flight_plan.h"
37#include "generated/modules.h"
38#include "state.h"
39
40// Check if rover firmware
41#ifndef ROVER_FIRMWARE
42#error "The module nps_fdm_rover is designed for rovers and doesn't support other firmwares!!"
43#endif
44
45#if (defined COMMAND_STEERING) && (defined COMMAND_THROTTLE) // STEERING ROVER PHYSICS
46
47// Friction coef, proportional to speed
48#ifndef NPS_ROVER_FRICTION
49#define NPS_ROVER_FRICTION 0.01f
50#endif
51
53
54// Maximum acceleration (m/s²)
55#ifndef NPS_ROVER_ACCELERATION
56#define NPS_ROVER_ACCELERATION 1.f
57#endif
58
60static float mu = NPS_ROVER_FRICTION;
61
62#endif
63
65
66#if (defined COMMAND_TURN) && (defined COMMAND_SPEED) // 2 wheels rover dynamic
67
68// Maximum speed (m/s)
69#ifndef NPS_ROVER_MAX_SPEED
70#define NPS_ROVER_MAX_SPEED 2.f
71#endif
72
73// Maximum turn rate (rad/s)
74#ifndef NPS_ROVER_TURN_RATE
75#define NPS_ROVER_TURN_RATE 3.f
76#endif
77
78// Accel 1st order time constant
79#ifndef NPS_ROVER_ACCEL_TAU
80#define NPS_ROVER_ACCEL_TAU 0.2f
81#endif
82
83// Turn rate 1st order time constant
84#ifndef NPS_ROVER_TURN_TAU
85#define NPS_ROVER_TURN_TAU 0.1f
86#endif
87
90static struct FirstOrderLowPass turn_filter;
91
92#endif // 2 wheels
93
94// NpsFdm structure
95struct NpsFdm fdm;
96
97// Reference point
98static struct LtpDef_d ltpdef;
99
100// Static functions declaration
101static void init_ltp(void);
102
104static struct NedCoor_d rover_pos;
105static struct NedCoor_d rover_vel;
106static struct NedCoor_d rover_acc;
107
108
110void nps_fdm_init(double dt)
111{
112 fdm.init_dt = dt; // (1 / simulation freq)
113 fdm.curr_dt = dt;
114 fdm.time = 0;
115
117 fdm.nan_count = 0;
118 fdm.pressure = -1;
120 fdm.total_pressure = -1;
122 fdm.temperature = -1;
124 init_ltp();
125
126#if (defined COMMAND_TURN) && (defined COMMAND_SPEED) // 2 wheels rover dynamic
129#endif
130}
131
132void nps_fdm_run_step(bool launch __attribute__((unused)), double *commands, int commands_nb __attribute__((unused)))
133{
134 fdm.time += fdm.curr_dt;
135
136 /****************************************************************************
137 PHYSICAL MODEL
138 -------------
139 The physical model of your rover goes here. This physics takes place in
140 the LTP plane (so we transfer every integration step to NED and ECEF at the end).
141 */
142
143 // From previous step...
146 double phi = fdm.ltpprz_to_body_eulers.psi;
147
148 #if (defined COMMAND_STEERING) && (defined COMMAND_THROTTLE) // STEERING ROVER PHYSICS
149
150 // Steering rover cmds:
151 // COMMAND_STEERING -> delta parameter
152 // COMMAND_THROTTLE -> acceleration in heading direction
153
155 double delta = RadOfDeg(commands[COMMAND_STEERING] * MAX_DELTA);
156 double speed = FLOAT_VECT2_NORM(rover_vel);
157 double phi_d = tan(delta) / DRIVE_SHAFT_DISTANCE * speed;
159
160 // NED accel = R(psi) [accel; |V|*phi_d] - mu*V
161 rover_acc.x = accel * cos(phi) - speed * phi_d * sin(phi) - mu * rover_vel.x;
162 rover_acc.y = accel * sin(phi) + speed * phi_d * cos(phi) - mu * rover_vel.y;
163 // Velocities (EULER INTEGRATION)
166
167 #elif (defined COMMAND_TURN) && (defined COMMAND_SPEED) // 2 wheels rover dynamic
168
173 double vx = speed * cos(phi);
174 double vy = speed * sin(phi);
175 rover_acc.x = (vx - rover_vel.x) / fdm.curr_dt;
176 rover_acc.y = (vy - rover_vel.y) / fdm.curr_dt;
177 rover_vel.x = vx;
178 rover_vel.y = vy;
179
180 #else
181 #warning "The physics of this rover are not yet implemented in nps_fdm_rover!!"
182 #endif // STEERING ROVER PHYSICS
183
184 // Positions
187 // phi have to be contained in [-180º,180º). So:
188 phi += phi_d * fdm.curr_dt;
189 NormRadAngle(phi);
190 /****************************************************************************/
191 // Coordenates transformations |
192 // ----------------------------|
193
194 /* in ECEF */
198
199 /* in NED */
203
204 /* Height above sea level */
206
207 /* Eulers */
210
211 // Exporting Eulers to AHRS (in quaternions)
213
214 // Angular vel & acc
217
218}
219
220
221/**************************
222 ** Generating LTP plane **
223 **************************/
224
225static void init_ltp(void)
226{
227 struct LlaCoor_d llh_nav0;
228 llh_nav0.lat = RadOfDeg((double)NAV_LAT0 / 1e7);
229 llh_nav0.lon = RadOfDeg((double)NAV_LON0 / 1e7);
230 llh_nav0.alt = (double)(NAV_ALT0 + NAV_MSL0) / 1000.; /* Height above the ellipsoid */
231
232 struct EcefCoor_d ecef_nav0;
234
236 ltpdef.hmsl = (double)NAV_ALT0 / 1000.; /* Height above the geoid */
237
240 fdm.ltp_g.x = 0.;
241 fdm.ltp_g.y = 0.;
242 fdm.ltp_g.z = 0.; // accel data are already with the correct format
243
244
245#ifdef AHRS_H_X
249 PRINT_CONFIG_MSG("Using magnetic field as defined in airframe file.")
250#else
251 fdm.ltp_h.x = 1.;
252 fdm.ltp_h.y = 0.;
253 fdm.ltp_h.z = 0.;
254#endif
255
256}
257
258
259/*****************************************************/
260// Atmosphere function (we don't need that features) //
261void nps_fdm_set_wind(double speed __attribute__((unused)),
262 double dir __attribute__((unused)))
263{
264}
265
267 double wind_east __attribute__((unused)),
268 double wind_down __attribute__((unused)))
269{
270}
271
272void nps_fdm_set_turbulence(double wind_speed __attribute__((unused)),
273 int turbulence_severity __attribute__((unused)))
274{
275}
276
277void nps_fdm_set_temperature(double temp __attribute__((unused)),
278 double h __attribute__((unused)))
279{
280}
281
static void h(const real32_T x[7], const real32_T q[4], real32_T y[6])
double psi
in radians
double r
in rad/s^2
void double_quat_of_eulers(struct DoubleQuat *q, struct DoubleEulers *e)
#define FLOAT_VECT2_NORM(_v)
double y
in meters
double z
in meters
double lat
in radians
double hmsl
height in meters above mean sea level
double x
in meters
void ltp_def_from_ecef_d(struct LtpDef_d *def, struct EcefCoor_d *ecef)
void ecef_of_ned_vect_d(struct EcefCoor_d *ecef, struct LtpDef_d *def, struct NedCoor_d *ned)
void ned_of_ecef_vect_d(struct NedCoor_d *ned, struct LtpDef_d *def, struct EcefCoor_d *ecef)
void ned_of_ecef_point_d(struct NedCoor_d *ned, struct LtpDef_d *def, struct EcefCoor_d *ecef)
void ecef_of_ned_point_d(struct EcefCoor_d *ecef, struct LtpDef_d *def, struct NedCoor_d *ned)
void ecef_of_lla_d(struct EcefCoor_d *ecef, struct LlaCoor_d *lla)
vector in EarthCenteredEarthFixed coordinates
vector in Latitude, Longitude and Altitude
definition of the local (flat earth) coordinate system
vector in North East Down coordinates Units: meters
#define PPRZ_ISA_SEA_LEVEL_PRESSURE
ISA sea level standard atmospheric pressure in Pascal.
Definition pprz_isa.h:50
struct FloatVect3 speed_sp
PRINT_CONFIG_MSG("USE_INS_NAV_INIT defaulting to TRUE")
Simple first order low pass filter with bilinear transform.
static float update_first_order_low_pass(struct FirstOrderLowPass *filter, float value)
Update first order low pass filter state with a new value.
static void init_first_order_low_pass(struct FirstOrderLowPass *filter, float tau, float sample_time, float value)
Init first order low pass filter.
First order low pass filter structure.
uint16_t foo
Definition main_demo5.c:58
double time
Definition nps_fdm.h:46
struct NedCoor_d ltpprz_ecef_vel
velocity in ltppprz frame, wrt ECEF frame
Definition nps_fdm.h:79
struct DoubleVect3 ltp_g
Definition nps_fdm.h:104
double pressure_sl
pressure at sea level in Pascal
Definition nps_fdm.h:114
double init_dt
Definition nps_fdm.h:47
double total_pressure
total atmospheric pressure in Pascal
Definition nps_fdm.h:111
double hmsl
Definition nps_fdm.h:56
struct EcefCoor_d ecef_pos
Definition nps_fdm.h:53
struct NedCoor_d ltpprz_pos
Definition nps_fdm.h:54
struct NedCoor_d ltpprz_ecef_accel
accel in ltppprz frame, wrt ECEF frame
Definition nps_fdm.h:81
struct DoubleVect3 ltp_h
Definition nps_fdm.h:105
double dynamic_pressure
dynamic pressure in Pascal
Definition nps_fdm.h:112
struct DoubleEulers ltp_to_body_eulers
Definition nps_fdm.h:92
struct EcefCoor_d ecef_ecef_accel
acceleration in ECEF frame, wrt ECEF frame
Definition nps_fdm.h:66
double pressure
current (static) atmospheric pressure in Pascal
Definition nps_fdm.h:110
double curr_dt
Definition nps_fdm.h:48
struct DoubleQuat ltp_to_body_quat
Definition nps_fdm.h:91
struct DoubleRates body_ecef_rotvel
Definition nps_fdm.h:97
struct EcefCoor_d ecef_ecef_vel
velocity in ECEF frame, wrt ECEF frame
Definition nps_fdm.h:64
double temperature
current temperature in degrees Celcius
Definition nps_fdm.h:113
struct DoubleRates body_ecef_rotaccel
Definition nps_fdm.h:98
struct DoubleEulers ltpprz_to_body_eulers
Definition nps_fdm.h:94
bool on_ground
Definition nps_fdm.h:49
int nan_count
Definition nps_fdm.h:50
void nps_fdm_set_wind_ned(double wind_north, double wind_east, double wind_down)
void nps_fdm_init(double dt)
NPS FDM rover init.
static void init_ltp(void)
void nps_fdm_run_step(bool launch, double *commands, int commands_nb)
Minimum complexity flight dynamic model In legacy Paparazzi simulator, was implemented in OCaml and c...
static struct NedCoor_d rover_pos
Physical model structures.
void nps_fdm_set_temperature(double temp, double h)
Set temperature in degrees Celcius at given height h above MSL.
static struct NedCoor_d rover_vel
static struct NedCoor_d rover_acc
void nps_fdm_set_turbulence(double wind_speed, int turbulence_severity)
void nps_fdm_set_wind(double speed, double dir)
struct NpsFdm fdm
Holds all necessary NPS FDM state information.
static struct LtpDef_d ltpdef
Paparazzi generic algebra macros.
Paparazzi floating point algebra.
Paparazzi generic macros for geodetic calculations.
Paparazzi double-precision floating point math for geodetic calculations.
Paparazzi floating point math for geodetic calculations.
Paparazzi atmospheric pressure conversion utilities.
#define MAX_DELTA
Generated airframe.h from airframe.xml.
#define DRIVE_SHAFT_DISTANCE
static const ShellCommand commands[]
Definition shell_arch.c:78
static const float dir[]
API to get/set the generic vehicle states.
#define TRUE
Definition std.h:4