dRonin  adbada4
dRonin firmware
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
pios_flightgear.c
Go to the documentation of this file.
1 
14 /*
15  * This program is free software; you can redistribute it and/or modify
16  * it under the terms of the GNU General Public License as published by
17  * the Free Software Foundation; either version 3 of the License, or
18  * (at your option) any later version.
19  *
20  * This program is distributed in the hope that it will be useful, but
21  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
22  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
23  * for more details.
24  *
25  * You should have received a copy of the GNU General Public License along
26  * with this program; if not, see <http://www.gnu.org/licenses/>
27  *
28  * Additional note on redistribution: The copyright and license notices above
29  * must be maintained in each individual source file that is a derivative work
30  * of this source file; otherwise redistribution is prohibited.
31  */
32 
33 /* Project Includes */
34 #include "openpilot.h"
35 #include "pios.h"
36 #include "pios_thread.h"
37 #include "pios_flightgear.h"
38 #include <unistd.h>
39 #include <sys/types.h>
40 #include <errno.h>
41 #include <fcntl.h>
42 #include <fcntl.h>
43 
44 #include <actuatordesired.h>
45 
46 #if defined(_WIN32) || defined(WIN32) || defined(__MINGW32__)
47 # include <Winsock2.h>
48 #else
49 # include <sys/select.h>
50 #endif
51 
52 #ifndef INVALID_SOCKET
53 #define INVALID_SOCKET (-1)
54 #endif
55 
57  int socket;
58 
60 
61  struct sockaddr_in send_addr;
62 };
63 
67 static void PIOS_FLIGHTGEAR_RxTask(void *param)
68 {
69  flightgear_dev_t fg_dev = param;
70 
71  float accels[3], rates[3], lat, lng, alt, vels[3], temp, press;
72 
73  struct pios_sensor_accel_data accel_data = { };
74  struct pios_sensor_gyro_data gyro_data = { };
75 
76  int num = 0;
77 
78  while (true) {
79  char buf[320];
80 
81  ssize_t cnt = recv(fg_dev->socket, buf, sizeof(buf) - 1,
82  0);
83 
84  if (cnt < 0) {
85  perror("fg-recv");
86 
87  return;
88  }
89 
90  buf[cnt] = 0;
91 
92  int count;
93 
94  sscanf(buf, "%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%d",
95  accels, accels+1, accels+2,
96  rates, rates+1, rates+2,
97  &lat, &lng, &alt,
98  vels, vels+1, vels+2,
99  &temp, &press, &count);
100 
101  /* Feet per second^2 to m/s^2 */
102  accels[0] *= .3048;
103  accels[1] *= .3048;
104  accels[2] *= .3048;
105 
106  ActuatorDesiredData act_desired;
107 
108  ActuatorDesiredGet(&act_desired);
109 
110  char sendbuf[128];
111 
112  snprintf(sendbuf, sizeof(sendbuf), "%f,%f,%f,%f,%d\n",
113  act_desired.Roll,
114  -act_desired.Pitch,
115  act_desired.Yaw,
116  act_desired.Thrust,
117  num++);
118 
119  if (sendto(fg_dev->socket, sendbuf, strlen(sendbuf), 0,
120  (struct sockaddr *) &fg_dev->send_addr,
121  sizeof(fg_dev->send_addr)) < 0) {
122  perror("sendto");
123  }
124 
125  while (true) {
126  accel_data.x = accel_data.x * 0.3 + accels[0] * 0.7;
127  accel_data.y = accel_data.y * 0.3 + accels[1] * 0.7;
128  accel_data.z = accel_data.z * 0.3 + accels[2] * 0.7;
129 
130  gyro_data.x = gyro_data.x * 0.3 + rates[0] * 0.7;
131  gyro_data.y = gyro_data.y * 0.3 + rates[1] * 0.7;
132  gyro_data.z = gyro_data.z * 0.3 + rates[2] * 0.7;
133 
134  PIOS_Queue_Send(fg_dev->accel_queue, &accel_data, 0);
135  PIOS_Queue_Send(fg_dev->gyro_queue, &gyro_data, 0);
136 
137  fd_set r;
138 
139  FD_ZERO(&r);
140 
141  FD_SET(fg_dev->socket, &r);
142 
143  /* Seek ~3ms queue rate */
144  struct timeval timeout = {
145  .tv_sec = 0,
146  .tv_usec = 2800,
147  };
148 
149  select(fg_dev->socket + 1, &r, NULL, NULL, &timeout);
150 
151  if (FD_ISSET(fg_dev->socket, &r)) {
152  break;
153  }
154  }
155  }
156 
157 }
158 
162 int32_t PIOS_FLIGHTGEAR_Init(flightgear_dev_t *dev, uint16_t port)
163 {
164  flightgear_dev_t fg_dev = PIOS_malloc(sizeof(*fg_dev));
165  memset(fg_dev, 0, sizeof(*fg_dev));
166 
167  /* assign socket */
168  fg_dev->socket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
169 
170 #if defined(_WIN32) || defined(WIN32) || defined(__MINGW32__)
171  char optval = 1;
172  /* char optoff = 0;
173 
174  setsockopt(fg_dev->socket, IPPROTO_IPV6, IPV6_V6ONLY, &optoff, sizeof(optoff));*/
175 #else
176  int optval = 1;
177 #endif
178 
179  /* Allow reuse of address if you restart. */
180  setsockopt(fg_dev->socket, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
181 
182  printf("binding sockets on ports %d, %d\n", port, port+1);
183 
184  const struct in_addr any_addr = {
185  .s_addr = (INADDR_ANY) /* parentheses to silence clang warning */
186  };
187 
188  struct sockaddr_in saddr = {
189  .sin_family = AF_INET,
190  .sin_addr = any_addr,
191  .sin_port = htons(port)
192  };
193 
194  fg_dev->send_addr = (struct sockaddr_in) {
195  .sin_family = AF_INET,
196  .sin_addr = any_addr,
197  .sin_port = htons(port + 1)
198  };
199 
200  int res = bind(fg_dev->socket, (struct sockaddr*)&saddr,
201  sizeof(saddr));
202  if (res == -1) {
203  perror("Binding socket failed");
204  exit(EXIT_FAILURE);
205  }
206 
207  fg_dev->accel_queue = PIOS_Queue_Create(2, sizeof(struct pios_sensor_accel_data));
208  if (fg_dev->accel_queue == NULL) {
209  exit(1);
210  }
211 
212  fg_dev->gyro_queue = PIOS_Queue_Create(2, sizeof(struct pios_sensor_gyro_data));
213  if (fg_dev->gyro_queue == NULL) {
214  exit(1);
215  }
216 
219 
222 
224 
225  struct pios_thread *fg_handle = PIOS_Thread_Create(
226  PIOS_FLIGHTGEAR_RxTask, "pios_fgear",
229 
230  (void) fg_handle;
231 
232  printf("fg dev %p - socket %i opened\n", fg_dev, fg_dev->socket);
233 
234  *dev = fg_dev;
235 
236  return res;
237 }
238 
struct pios_queue * PIOS_Queue_Create(size_t queue_length, size_t item_size)
Definition: pios_queue.c:47
void PIOS_SENSORS_SetMaxGyro(int32_t rate)
Set the maximum gyro rate in deg/s.
Definition: pios_sensors.c:162
Main PiOS header to include all the compiled in PiOS options.
const uint8_t count
Definition: panel.c:515
int32_t PIOS_FLIGHTGEAR_Init(flightgear_dev_t *dev, uint16_t port)
struct pios_queue * accel_queue
FlightGear driver header.
void * PIOS_malloc(size_t size)
Definition: pios_heap.c:125
bool PIOS_Queue_Send(struct pios_queue *queuep, const void *itemp, uint32_t timeout_ms)
Definition: pios_queue.c:141
uint32_t lat
Definition: msp_messages.h:97
static void PIOS_FLIGHTGEAR_RxTask(void *param)
struct pios_queue * gyro_queue
#define PIOS_THREAD_STACK_SIZE_MIN
Definition: pios_thread.h:55
struct _msp_pid_item alt
Definition: msp_messages.h:99
Pios sensor structure for generic accel data.
Definition: pios_sensors.h:46
struct sockaddr_in send_addr
struct pios_thread * PIOS_Thread_Create(void(*fp)(void *), const char *namep, size_t stack_bytes, void *argp, enum pios_thread_prio_e prio)
Definition: pios_thread.c:89
int32_t PIOS_SENSORS_Register(enum pios_sensor_type type, struct pios_queue *queue)
Register a queue-based sensor with the PIOS_SENSORS interface.
Definition: pios_sensors.c:82
Pios sensor structure for generic gyro data.
Definition: pios_sensors.h:38
void PIOS_SENSORS_SetSampleRate(enum pios_sensor_type type, uint32_t sample_rate)
Set the sample rate of a sensor (Hz)
Definition: pios_sensors.c:172
Includes PiOS and core architecture components.
int printf(const char *format,...)
int snprintf(char *buf, size_t count, const char *format,...)