Paparazzi UAS v7.0_unstable
Paparazzi is a free software Unmanned Aircraft System.
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
nps_ivy.c
Go to the documentation of this file.
1#include "nps_ivy.h"
2
3#include <stdlib.h>
4#include <stdio.h>
5#include <sys/types.h>
6#include <unistd.h>
7#include <Ivy/ivy.h>
8
9#include <Ivy/ivyloop.h>
10#include <pthread.h>
11
12#include "generated/airframe.h"
15#include "nps_main.h"
16#include "nps_autopilot.h"
17#include "nps_fdm.h"
18#include "nps_sensors.h"
19#include "nps_atmosphere.h"
20
21#include "generated/settings.h"
22#include "pprzlink/dl_protocol.h"
24
25#if USE_GPS
26#include "modules/gps/gps.h"
27#endif
28
30pthread_t th_ivy_main; // runs main Ivy loop
32static int seq = 1;
33static int ap_launch_index;
34static pthread_mutex_t ivy_mutex; // mutex for ivy send
35
36/* Gaia Ivy functions */
37static void on_WORLD_ENV(IvyClientPtr app __attribute__((unused)),
38 void *user_data __attribute__((unused)),
39 int argc, char *argv[]);
40
41/* Datalink Ivy functions */
42static void on_DL_SETTING(IvyClientPtr app __attribute__((unused)),
43 void *user_data __attribute__((unused)),
44 int argc, char *argv[]);
45
46void* ivy_main_loop(void* data __attribute__((unused)));
47
48int find_launch_index(void);
49
50
51void* ivy_main_loop(void* data __attribute__((unused)))
52{
54
55 return NULL;
56}
57
58void nps_ivy_init(char *ivy_bus)
59{
60 const char *agent_name = AIRFRAME_NAME"_NPS";
61 const char *ready_msg = AIRFRAME_NAME"_NPS Ready";
63
64 // bind on a general WORLD_ENV (not a reply to request)
65 IvyBindMsg(on_WORLD_ENV, NULL, "^(\\S*) WORLD_ENV (\\S*) (\\S*) (\\S*) (\\S*) (\\S*) (\\S*)");
66
67 // to be able to change datalink_enabled setting back on
68 IvyBindMsg(on_DL_SETTING, NULL, "^(\\S*) DL_SETTING (\\S*) (\\S*) (\\S*)");
69
70#ifdef __APPLE__
71 const char *default_ivy_bus = "224.255.255.255";
72#else
73 const char *default_ivy_bus = "127.255.255.255";
74#endif
75 if (ivy_bus == NULL) {
77 } else {
78 IvyStart(ivy_bus);
79 }
80
82
84
85 // Launch separate thread with IvyMainLoop()
87
88}
89
90/*
91 * Parse WORLD_ENV message from gaia.
92 *
93 */
95 void *user_data __attribute__((unused)),
96 int argc, char *argv[])
97{
98 if (argc < 6) { return; }
99
100 // wind speed in m/s
101 struct FloatVect3 wind;
102 wind.x = atof(argv[1]); //east
103 wind.y = atof(argv[2]); //north
104 wind.z = atof(argv[3]); //up
105
106 /* set wind speed in NED */
107 nps_atmosphere_set_wind_ned(wind.y, wind.x, -wind.z);
108
109 /* not used so far */
110 //float ir_contrast = atof(argv[4]);
111
112 /* set new time factor */
114
115#if USE_GPS
116 // directly set gps fix in modules/gps/gps_sim_nps.h
117 gps_has_fix = atoi(argv[6]); // gps_availability
118#endif
119
120}
121
122/*
123 * Send a WORLD_ENV_REQ message
124 */
125
126
128{
130
131 // First unbind from previous request if needed
132 if (ivyPtr != NULL) {
134 ivyPtr = NULL;
135 }
136
137 int pid = (int)getpid();
138
139 // Bind to the reply
140 ivyPtr = IvyBindMsg(on_WORLD_ENV, NULL, "^%d_%d (\\S*) WORLD_ENV (\\S*) (\\S*) (\\S*) (\\S*) (\\S*) (\\S*)", pid, seq);
141
142 // Send actual request
143 struct NpsFdm fdm_ivy;
144 memcpy(&fdm_ivy, &fdm, sizeof(struct NpsFdm));
145
146 IvySendMsg("nps %d_%d WORLD_ENV_REQ %f %f %f %f %f %f",
147 pid, seq,
148 DegOfRad(fdm_ivy.lla_pos_pprz.lat),
149 DegOfRad(fdm_ivy.lla_pos_pprz.lon),
150 (fdm_ivy.hmsl),
151 (fdm_ivy.ltpprz_pos.x),
152 (fdm_ivy.ltpprz_pos.y),
153 (fdm_ivy.ltpprz_pos.z));
154 seq++;
155
157
159}
160
162{
163#ifdef AP_LAUNCH
164 return AP_LAUNCH - 1; // index of AP_LAUNCH starts at 1, but it should be 0 here
165#else
166#if NB_SETTING > 0
167 static const char ap_launch[] = "aut_lau"; // short name
169
170 // list through the settings
171 // TODO: maybe search for a substring with if(strstr(sent, word) != NULL)
172 for (uint8_t idx=0;idx<NB_SETTING;idx++) {
173 if (strcmp(ap_settings[idx],ap_launch) == 0) {
174 return (int)idx;
175 }
176 }
177#endif
178 return -1;
179#endif
180}
181
183 void *user_data __attribute__((unused)),
184 int argc, char *argv[])
185{
186 if (argc < 3) { return; }
187
188 if (atoi(argv[1]) != AC_ID) {
189 return;
190 }
191
192 /* HACK:
193 * we actually don't want to allow changing settings if datalink is disabled,
194 * but since we currently change this variable via settings we have to allow it
195 * TODO: only allow changing the datalink_enabled setting
196 */
197 uint8_t index = atoi(argv[2]);
198 float value = atof(argv[3]);
199#ifndef HITL
200 if (!datalink_enabled) {
201 DlSetting(index, value);
203 }
204#endif
205 printf("setting %d %f\n", index, value);
206
207 /*
208 * In case of HITL, update nps_autopilot.launch from DL_SETTINGS
209 * so the plane can be properly launched.
210 *
211 * In case of STIL nps_update_launch_from_dl() is an empty function
212 */
213 if ((ap_launch_index >= 0) || (ap_launch_index < NB_SETTING)) {
214 if (index==ap_launch_index){
216 }
217 }
218}
219
220
222{
223 struct NpsFdm fdm_ivy;
224 struct NpsSensors sensors_ivy;
225
226 // make a local copy with mutex
228 memcpy(&fdm_ivy, fdm_data, sizeof(fdm));
231
232 // protect Ivy thread
234
235 IvySendMsg("%d NPS_RATE_ATTITUDE %f %f %f %f %f %f",
236 AC_ID,
237 DegOfRad(fdm_ivy.body_ecef_rotvel.p),
238 DegOfRad(fdm_ivy.body_ecef_rotvel.q),
239 DegOfRad(fdm_ivy.body_ecef_rotvel.r),
240 DegOfRad(fdm_ivy.ltp_to_body_eulers.phi),
241 DegOfRad(fdm_ivy.ltp_to_body_eulers.theta),
242 DegOfRad(fdm_ivy.ltp_to_body_eulers.psi));
243 IvySendMsg("%d NPS_POS_LLH %f %f %f %f %f %f %f %f %f",
244 AC_ID,
245 (fdm_ivy.lla_pos_pprz.lat),
246 (fdm_ivy.lla_pos_geod.lat),
247 (fdm_ivy.lla_pos_geoc.lat),
248 (fdm_ivy.lla_pos_pprz.lon),
249 (fdm_ivy.lla_pos_geod.lon),
250 (fdm_ivy.lla_pos_pprz.alt),
251 (fdm_ivy.lla_pos_geod.alt),
252 (fdm_ivy.agl),
253 (fdm_ivy.hmsl));
254 IvySendMsg("%d NPS_SPEED_POS %f %f %f %f %f %f %f %f %f",
255 AC_ID,
256 (fdm_ivy.ltpprz_ecef_accel.x),
257 (fdm_ivy.ltpprz_ecef_accel.y),
258 (fdm_ivy.ltpprz_ecef_accel.z),
259 (fdm_ivy.ltpprz_ecef_vel.x),
260 (fdm_ivy.ltpprz_ecef_vel.y),
261 (fdm_ivy.ltpprz_ecef_vel.z),
262 (fdm_ivy.ltpprz_pos.x),
263 (fdm_ivy.ltpprz_pos.y),
264 (fdm_ivy.ltpprz_pos.z));
265 IvySendMsg("%d NPS_GYRO_BIAS %f %f %f",
266 AC_ID,
267 DegOfRad(RATE_FLOAT_OF_BFP(sensors_ivy.gyro.bias_random_walk_value.x) + sensors_ivy.gyro.bias_initial.x),
268 DegOfRad(RATE_FLOAT_OF_BFP(sensors_ivy.gyro.bias_random_walk_value.y) + sensors_ivy.gyro.bias_initial.y),
269 DegOfRad(RATE_FLOAT_OF_BFP(sensors_ivy.gyro.bias_random_walk_value.z) + sensors_ivy.gyro.bias_initial.z));
270
271 /* transform magnetic field to body frame */
272 struct DoubleVect3 h_body;
273 double_quat_vmult(&h_body, &fdm_ivy.ltp_to_body_quat, &fdm_ivy.ltp_h);
274
275 IvySendMsg("%d NPS_SENSORS_SCALED %f %f %f %f %f %f",
276 AC_ID,
277 ((sensors_ivy.accel.value.x - sensors_ivy.accel.neutral.x) / NPS_ACCEL_SENSITIVITY_XX),
278 ((sensors_ivy.accel.value.y - sensors_ivy.accel.neutral.y) / NPS_ACCEL_SENSITIVITY_YY),
279 ((sensors_ivy.accel.value.z - sensors_ivy.accel.neutral.z) / NPS_ACCEL_SENSITIVITY_ZZ),
280 h_body.x,
281 h_body.y,
282 h_body.z);
283
284 IvySendMsg("%d NPS_WIND %f %f %f",
285 AC_ID,
286 fdm_ivy.wind.x,
287 fdm_ivy.wind.y,
288 fdm_ivy.wind.z);
289
291
294 }
295}
#define sensors(...)
Device independent GPS code (interface)
bool gps_has_fix
Definition gps_sim_nps.c:30
void double_quat_vmult(struct DoubleVect3 *v_out, struct DoubleQuat *q, struct DoubleVect3 *v_in)
#define RATE_FLOAT_OF_BFP(_ai)
uint16_t foo
Definition main_demo5.c:58
void nps_atmosphere_set_wind_ned(double wind_north, double wind_east, double wind_down)
Atmosphere model (pressure, wind) for NPS.
struct NpsFdm fdm
Holds all necessary NPS FDM state information.
void * ivy_main_loop(void *data)
Definition nps_ivy.c:51
static pthread_mutex_t ivy_mutex
Definition nps_ivy.c:34
pthread_t th_ivy_main
Definition nps_ivy.c:30
static void on_DL_SETTING(IvyClientPtr app, void *user_data, int argc, char *argv[])
Definition nps_ivy.c:182
void nps_ivy_send_WORLD_ENV_REQ(void)
Definition nps_ivy.c:127
static void on_WORLD_ENV(IvyClientPtr app, void *user_data, int argc, char *argv[])
Definition nps_ivy.c:94
bool nps_ivy_send_world_env
Definition nps_ivy.c:29
static MsgRcvPtr ivyPtr
Definition nps_ivy.c:31
static int seq
Definition nps_ivy.c:32
static int ap_launch_index
Definition nps_ivy.c:33
void nps_ivy_display(struct NpsFdm *fdm_data, struct NpsSensors *sensors_data)
Definition nps_ivy.c:221
void nps_ivy_init(char *ivy_bus)
Definition nps_ivy.c:58
int find_launch_index(void)
Definition nps_ivy.c:161
void nps_update_launch_from_dl(uint8_t value)
void nps_set_time_factor(float time_factor)
pthread_mutex_t fdm_mutex
static uint32_t idx
Paparazzi double precision floating point algebra.
Paparazzi floating point algebra.
unsigned char uint8_t
Typedef defining 8 bit unsigned char type.