4545#include < string.h>
4646#include < sys/types.h>
4747#include < drivers/drv_led.h>
48- #ifndef __PX4_QURT
49- #include < sys/socket.h>
50- #include < netinet/in.h>
51- #endif
48+
5249#include " simulator.h"
53- #include < drivers/drv_hrt.h>
5450
5551using namespace simulator ;
5652
5753static px4_task_t g_sim_task = -1 ;
5854
5955Simulator *Simulator::_instance = NULL ;
6056
57+ static const uint8_t mavlink_message_lengths[256 ] = MAVLINK_MESSAGE_LENGTHS;
58+ static const uint8_t mavlink_message_crcs[256 ] = MAVLINK_MESSAGE_CRCS;
59+
6160Simulator *Simulator::getInstance ()
6261{
6362 return _instance;
@@ -100,6 +99,83 @@ int Simulator::start(int argc, char *argv[])
10099 return ret;
101100}
102101
102+ void Simulator::poll_topics () {
103+ // copy new data if available
104+ bool updated;
105+ orb_check (_actuator_outputs_sub, &updated);
106+ if (updated) {
107+ orb_copy (ORB_ID (actuator_outputs), _actuator_outputs_sub, &_actuators);
108+ }
109+
110+ orb_check (_vehicle_attitude_sub, &updated);
111+ if (updated) {
112+ orb_copy (ORB_ID (vehicle_attitude), _vehicle_attitude_sub, &_attitude);
113+ }
114+ }
115+
116+ void Simulator::send_data () {
117+ // check if it's time to send new data
118+ hrt_abstime time_now = hrt_absolute_time ();
119+ if (time_now - _time_last >= (hrt_abstime)(_interval * 1000 )) {
120+ _time_last = time_now;
121+ mavlink_message_t msg;
122+ pack_actuator_message (&msg);
123+ send_mavlink_message (MAVLINK_MSG_ID_SERVO_OUTPUT_RAW, &msg, 200 );
124+ // can add more messages here, can also setup different timings
125+ }
126+ }
127+
128+ void Simulator::pack_actuator_message (mavlink_message_t *msg) {
129+ // pack message and send
130+ mavlink_servo_output_raw_t actuator_msg;
131+
132+ actuator_msg.time_usec = hrt_absolute_time ();
133+ actuator_msg.port = 8 ; // hardcoded for now
134+ actuator_msg.servo1_raw = _actuators.output [0 ];
135+ actuator_msg.servo2_raw = _actuators.output [1 ];
136+ actuator_msg.servo3_raw = _actuators.output [2 ];
137+ actuator_msg.servo4_raw = _actuators.output [3 ];
138+ actuator_msg.servo5_raw = _actuators.output [4 ];
139+ actuator_msg.servo6_raw = _actuators.output [5 ];
140+ actuator_msg.servo7_raw = _actuators.output [6 ];
141+ actuator_msg.servo8_raw = _actuators.output [7 ];
142+
143+ // encode the message
144+ mavlink_msg_servo_output_raw_encode (1 , 100 , msg, &actuator_msg);
145+ }
146+
147+ void Simulator::send_mavlink_message (const uint8_t msgid, const void *msg, uint8_t component_ID) {
148+ uint8_t payload_len = mavlink_message_lengths[msgid];
149+
150+ uint8_t buf[MAVLINK_MAX_PACKET_LEN];
151+
152+ /* header */
153+ buf[0 ] = MAVLINK_STX;
154+ buf[1 ] = payload_len;
155+ /* no idea which numbers should be here*/
156+ buf[2 ] = 100 ;
157+ buf[3 ] = 1 ;
158+ buf[4 ] = component_ID;
159+ buf[5 ] = msgid;
160+
161+ /* payload */
162+ memcpy (&buf[MAVLINK_NUM_HEADER_BYTES],&msg, payload_len);
163+
164+ /* checksum */
165+ uint16_t checksum;
166+ crc_init (&checksum);
167+ crc_accumulate_buffer (&checksum, (const char *) &buf[1 ], MAVLINK_CORE_HEADER_LEN + payload_len);
168+ crc_accumulate (mavlink_message_crcs[msgid], &checksum);
169+
170+ buf[MAVLINK_NUM_HEADER_BYTES + payload_len] = (uint8_t )(checksum & 0xFF );
171+ buf[MAVLINK_NUM_HEADER_BYTES + payload_len + 1 ] = (uint8_t )(checksum >> 8 );
172+
173+ ssize_t len = sendto (_fd, buf, sizeof (buf), 0 , (struct sockaddr *)&_srcaddr, _addrlen);
174+ if (len <= 0 ) {
175+ PX4_WARN (" Failed sending mavlink message" );
176+ }
177+ }
178+
103179void Simulator::fill_sensors_from_imu_msg (struct sensor_combined_s *sensor, mavlink_highres_imu_t *imu) {
104180 hrt_abstime timestamp = hrt_absolute_time ();
105181 sensor->timestamp = timestamp;
@@ -221,7 +297,6 @@ void Simulator::publishSensorsCombined() {
221297 // advertise
222298 _sensor_combined_pub = orb_advertise (ORB_ID (sensor_combined), &sensors);
223299
224-
225300 hrt_abstime time_last = hrt_absolute_time ();
226301 uint64_t delta;
227302 for (;;) {
@@ -270,46 +345,52 @@ void Simulator::updateSamples()
270345 // mag report
271346 struct mag_report mag;
272347 memset (&mag, 0 ,sizeof (mag));
348+
273349 // init publishers
274350 _baro_pub = orb_advertise (ORB_ID (sensor_baro), &baro);
275351 _accel_pub = orb_advertise (ORB_ID (sensor_accel), &accel);
276352 _gyro_pub = orb_advertise (ORB_ID (sensor_gyro), &gyro);
277353 _mag_pub = orb_advertise (ORB_ID (sensor_mag), &mag);
278354
279- // get samples from external provider
280- struct sockaddr_in myaddr;
281- struct sockaddr_in srcaddr;
282- socklen_t addrlen = sizeof (srcaddr);
283- int len, fd;
284- const int buflen = 200 ;
285- const int port = 14550 ;
286- unsigned char buf[buflen];
355+ // subscribe to topics
356+ _actuator_outputs_sub = orb_subscribe (ORB_ID (actuator_outputs));
357+ _vehicle_attitude_sub = orb_subscribe (ORB_ID (vehicle_attitude));
358+
359+ // try to setup udp socket for communcation with simulator
360+ memset ((char *)&_myaddr, 0 , sizeof (_myaddr));
361+ _myaddr.sin_family = AF_INET;
362+ _myaddr.sin_addr .s_addr = htonl (INADDR_ANY);
363+ _myaddr.sin_port = htons (_port);
287364
288- if ((fd = socket (AF_INET, SOCK_DGRAM, 0 )) < 0 ) {
365+ if ((_fd = socket (AF_INET, SOCK_DGRAM, 0 )) < 0 ) {
289366 PX4_WARN (" create socket failed\n " );
290367 return ;
291368 }
292369
293- memset ((char *)&myaddr, 0 , sizeof (myaddr));
294- myaddr.sin_family = AF_INET;
295- myaddr.sin_addr .s_addr = htonl (INADDR_ANY);
296- myaddr.sin_port = htons (port);
297-
298- if (bind (fd, (struct sockaddr *)&myaddr, sizeof (myaddr)) < 0 ) {
370+ if (bind (_fd, (struct sockaddr *)&_myaddr, sizeof (_myaddr)) < 0 ) {
299371 PX4_WARN (" bind failed\n " );
300372 return ;
301373 }
302374
375+ // this is used to time message sending
376+ _time_last = hrt_absolute_time ();
377+
378+ // make socket non-blocking
379+ int flags = fcntl (_fd,F_GETFL);
380+ flags |= O_NONBLOCK;
381+ fcntl (_fd, F_SETFL, flags);
382+
383+ int len = 0 ;
303384 // wait for new mavlink messages to arrive
304385 for (;;) {
305- len = 0 ;
306- len = recvfrom (fd, buf, buflen , 0 , (struct sockaddr *)&srcaddr , &addrlen );
386+ // see if we can receive data from simulator
387+ len = recvfrom (_fd, _buf, _buflen , 0 , (struct sockaddr *)&_srcaddr , &_addrlen );
307388 if (len > 0 ) {
308389 mavlink_message_t msg;
309390 mavlink_status_t status;
310391 for (int i = 0 ; i < len; ++i)
311392 {
312- if (mavlink_parse_char (MAVLINK_COMM_0, buf [i], &msg, &status))
393+ if (mavlink_parse_char (MAVLINK_COMM_0, _buf [i], &msg, &status))
313394 {
314395 // have a message, handle it
315396 handle_message (&msg);
@@ -324,35 +405,16 @@ void Simulator::updateSamples()
324405 gyro.timestamp = time_last;
325406 mag.timestamp = time_last;
326407 // publish the sensor values
327- // printf("Publishing SensorsCombined\n");
328408 orb_publish (ORB_ID (sensor_baro), _baro_pub, &baro);
329409 orb_publish (ORB_ID (sensor_accel), _accel_pub, &baro);
330410 orb_publish (ORB_ID (sensor_gyro), _gyro_pub, &baro);
331411 orb_publish (ORB_ID (sensor_mag), _mag_pub, &mag);
332- }
333412
334- /*
335- for (;;) {
336- len = recvfrom(fd, buf, buflen, 0, (struct sockaddr *)&srcaddr, &addrlen);
337- if (len > 0) {
338- if (len == sizeof(RawMPUData)) {
339- PX4_DBG("received: MPU data\n");
340- _mpu.writeData(buf);
341- }
342- else if (len == sizeof(RawAccelData)) {
343- PX4_DBG("received: accel data\n");
344- _accel.writeData(buf);
345- }
346- else if (len == sizeof(RawBaroData)) {
347- PX4_DBG("received: accel data\n");
348- _baro.writeData(buf);
349- }
350- else {
351- PX4_DBG("bad packet: len = %d\n", len);
352- }
353- }
413+ // see if there is new data to send to simulator
414+ poll_topics ();
415+ send_data ();
416+ usleep (10000 );
354417 }
355- */
356418}
357419#endif
358420
0 commit comments