RflySimSDK v3.08
RflySimSDK说明文档
载入中...
搜索中...
未找到
rfly_mavlink.h
1#pragma once
2
4#include <math.h>
5#include <stdio.h>
6#include <string.h>
7#include <vector>
8#include <algorithm> // std::transform
9#include <cctype>
10#include "rfly_data.h"
11#include "rfly_udp.h"
12
13#define MAX_BUF_LEN 300 // More than max mavlink msg len
14
15
16enum PX4_FLIGHTMODE{
17 PX4_FLIGHTMODE_MANUAL = 1,
18 PX4_FLIGHTMODE_ALT,
19 PX4_FLIGHTMODE_POS,
20 PX4_FLIGHTMODE_TAKEOFF,
21 PX4_FLIGHTMODE_LAND,
22 PX4_FLIGHTMODE_MISSION,
23 PX4_FLIGHTMODE_RTL,
24 PX4_FLIGHTMODE_STABILIZED,
25 PX4_FLIGHTMODE_OFFBOARD,
26 PX4_FLIGHTMODE_AUTO_READY,
27 PX4_FLIGHTMODE_AUTO_LOITER
28};
29
30enum PX4_CUSTOM_MAIN_MODE {
31 PX4_CUSTOM_MAIN_MODE_MANUAL = 1,
32 PX4_CUSTOM_MAIN_MODE_ALTCTL,
33 PX4_CUSTOM_MAIN_MODE_POSCTL,
34 PX4_CUSTOM_MAIN_MODE_AUTO,
35 PX4_CUSTOM_MAIN_MODE_ACRO,
36 PX4_CUSTOM_MAIN_MODE_OFFBOARD,
37 PX4_CUSTOM_MAIN_MODE_STABILIZED,
38 PX4_CUSTOM_MAIN_MODE_RATTITUDE_LEGACY,
39 PX4_CUSTOM_MAIN_MODE_SIMPLE /* unused, but reserved for future use */
40};
41
42enum PX4_CUSTOM_SUB_MODE_AUTO {
43 PX4_CUSTOM_SUB_MODE_AUTO_READY = 1,
44 PX4_CUSTOM_SUB_MODE_AUTO_TAKEOFF,
45 PX4_CUSTOM_SUB_MODE_AUTO_LOITER,
46 PX4_CUSTOM_SUB_MODE_AUTO_MISSION,
47 PX4_CUSTOM_SUB_MODE_AUTO_RTL,
48 PX4_CUSTOM_SUB_MODE_AUTO_LAND,
49 PX4_CUSTOM_SUB_MODE_AUTO_RESERVED_DO_NOT_USE, // was PX4_CUSTOM_SUB_MODE_AUTO_RTGS, deleted 2020-03-05
50 PX4_CUSTOM_SUB_MODE_AUTO_FOLLOW_TARGET,
51 PX4_CUSTOM_SUB_MODE_AUTO_PRECLAND
52};
53
54enum PX4_CUSTOM_SUB_MODE_POSCTL {
55 PX4_CUSTOM_SUB_MODE_POSCTL_POSCTL = 0,
56 PX4_CUSTOM_SUB_MODE_POSCTL_ORBIT
57};
58
60 struct {
61 uint16_t reserved;
62 uint8_t main_mode;
63 uint8_t sub_mode;
64 };
65 uint32_t data;
66 float data_float;
67 struct {
68 uint16_t reserved_hl;
69 uint16_t custom_mode_hl;
70 };
71};
72
73
74
76 bool isHeartRec=false;
77 bool isLocalNed=false;
78 bool isGlobPos=false;
79 bool isGpsHome=false;
80 int selfCheckState=0; //-1:faild, 0 inited, 1:uav connected, 2. get local pos, 3. can offboard, 4. can armed, 5. checkPassed
81
82 uint8_t sysID=255;
83 uint8_t compID=1;
84 uint8_t TargetSysID;
85 uint8_t TargetCompID;
86
87 uint32_t custom_mode; /*< A bitfield for use for autopilot-specific flags*/
88 uint8_t base_mode; /*< System mode bitmap.*/
89 uint8_t system_status; /*< System status flag.*/
90 uint32_t time_boot_ms;
91 //float initYaw;
92 //float yawOffset;
93 double batteryInfo[6];
94 double healthInfo[10];
95
96 bool isFailSafeEn=false;
97 bool isArmed=false;
98 bool isStanby=false;
99 bool isActive=false;
100 mavlink_sys_status_t sysStatus;
101 uint8_t landed_state=0;
102
103 bool isLowBatt=false;
104 bool isHighLoad=false;
105 bool isDropComm=false;
106 bool isOffboard=false;
107 PX4_FLIGHTMODE flyMode=PX4_FLIGHTMODE_MANUAL;
108 double obstacle[4]; // [0] id for obstacle, [1-3] x,y,z position for obstacle
109};
110
112 public:
113
114 RflySimData data;
115 MavStateData mavState;
116 UDPServer udp;
117 //MavHealthData phm;
118 std::string TargetIP;
119 int TargetPort;
120 int CopterID;
121 int RecvPort;
122 std::string RecvIP;
123 char buf[MAX_BUF_LEN+1];
124 bool isUpdate=false;
125 bool isRcc=false;
126 double GpsOrin[3]={0};
127
128
129 int SelfCheckMainState=0;
130 int SelfCheckSubState=0;
131 double lastTime=0;
132
133
134 int offCtrlState=0;
135 double offLastTime=0;
136
137 //SOut2Simulator m_show3d;
138 uint64_t m_start_time = 0;
139
140 RflyMavlink(){
141
142 }
143 ~RflyMavlink(){
144
145 }
146
147
148 bool RecvNoblock(){
149 int retry = 0;
150 while(true){ // Read all data in the upd buf zone
151 int recvlen=udp.RecvNoblock(buf,RecvIP,RecvPort,MAX_BUF_LEN);
152
153 // Five times has no useful message, will break
154 if (udp.needFilter && (RecvIP != TargetIP)){
155 retry++;
156 if (retry > 5)
157 break;
158 continue;
159 }
160 retry = 0;
161
162 if(recvlen>0){
163 mavlink_message_t message;
164 mavlink_status_t status;
165 uint8_t msgReceived = false;
166
167 if ((uint8_t)(buf[0]) == 0xEF){
168 // std::cout << "receive 0xEF" << std::endl;
169 onUdpMessage((uint8_t*)buf, recvlen);
170 }
171 else{
172 for(int i = 0 ; i < recvlen ; ++i){
173 msgReceived = mavlink_parse_char(MAVLINK_COMM_1, (uint8_t)buf[i], &message, &status);
174 if(msgReceived){
175 onMavLinkMessage(message);
176 isUpdate=true;
177 }
178 }
179 }
180 }else{
181 break;
182 }
183 }
184 return isUpdate;
185 }
186
187 void onUdpMessage(uint8_t *buf, int recvlen){
188 if (recvlen < 33){
189 std::cout << "expect recvlen >=33, receive udp msg with length "<< recvlen << std::endl;
190 return;
191 }
192 // std::cout << "received obstacle position: ";
193 for (int i = 0; i < 4; i++){
194 double received_double;
195 memcpy(&received_double, &(buf[1+8*i]), sizeof(double));
196 mavState.obstacle[i] = received_double;
197 // std::cout << received_double << "\t";
198 }
199 // std::cout << std::endl;
200 }
201
202
203 void onMavLinkMessage(mavlink_message_t message){
204
205 switch (message.msgid){
206 case MAVLINK_MSG_ID_HEARTBEAT:{
207 mavlink_heartbeat_t MavHartt;
208 mavlink_msg_heartbeat_decode(&message, &MavHartt);
209 // ignore QGC msg
210 if (MavHartt.custom_mode == 0)
211 break;
212 if (!mavState.isHeartRec){
213 mavState.isHeartRec = true;
214 mavState.TargetSysID = message.sysid;
215 mavState.TargetCompID = message.compid;
216 std::cout<<"Drone #"<<CopterID<<": "<<"Heartbeat for SysID "<<std::to_string(message.sysid)<<" and CompID "<<std::to_string(message.compid)<<std::endl;
217 //isLocalNed
218 }
219 mavState.base_mode = MavHartt.base_mode;
220 mavState.custom_mode = MavHartt.custom_mode;
221 mavState.system_status = MavHartt.system_status;
222
223 if(mavState.system_status==3){
224 mavState.isStanby=true;
225 }else{
226 mavState.isStanby=false;
227 }
228
229 if(mavState.system_status==4){
230 mavState.isActive=true;
231 }else{
232 mavState.isActive=false;
233 }
234
235 if ((mavState.base_mode & static_cast<uint8_t>(MAV_MODE_FLAG::MAV_MODE_FLAG_SAFETY_ARMED)) > 0) {
236 if(!mavState.isArmed){
237 mavState.isArmed = true;
238 std::cout<<"Drone #"<<CopterID<<": "<<"PX4 Armed "<<std::endl;
239 }
240 }else{
241 if(mavState.isArmed){
242 mavState.isArmed = false;
243 std::cout<<"Drone #"<<CopterID<<": "<<"PX4 Disamed. "<<std::endl;
244 }
245 }
246
247 PX4_FLIGHTMODE fm;
248 getFlightMode_px4(MavHartt.custom_mode,fm);
249 if(fm!=mavState.flyMode){
250 std::string qstr=getFlightModeName_px4(fm);
251 std::cout<<"Drone #"<<CopterID<<": "<<qstr<<std::endl;
252 mavState.flyMode=fm;
253 }
254 if(fm==PX4_FLIGHTMODE_OFFBOARD){
255 mavState.isOffboard=true;
256 }
257 else{
258 mavState.isOffboard=false;
259 }
260
261 break;
262 }
263 // MAVLINK_MSG_ID_SYS_STATUS may not have
264 case MAVLINK_MSG_ID_SYS_STATUS:{
265 mavlink_msg_sys_status_decode(&message, &mavState.sysStatus);
266 mavState.batteryInfo[0] = mavState.sysStatus.battery_remaining;
267 mavState.batteryInfo[1] = mavState.sysStatus.voltage_battery;
268 mavState.batteryInfo[2] = mavState.sysStatus.current_battery;
269
270 if(mavState.sysStatus.battery_remaining>=0 && mavState.sysStatus.battery_remaining<10){
271 if (!mavState.isLowBatt){
272 mavState.isLowBatt=true;
273 std::cout<<"Drone #"<<CopterID<<": "<<"Low battery."<<std::endl;
274 }
275 }
276 if(mavState.sysStatus.load>900){
277 if (!mavState.isHighLoad){
278 mavState.isHighLoad=true;
279 std::cout<<"Drone #"<<CopterID<<": "<<"High CPU load."<<std::endl;
280 }
281 }
282
283 if(mavState.sysStatus.drop_rate_comm>80){
284 if (!mavState.isDropComm){
285 mavState.isDropComm=true;
286 std::cout<<"Drone #"<<CopterID<<": "<<"Communication high drop rate."<<std::endl;
287 }
288 }
289 break;
290 }
291
292 case MAVLINK_MSG_ID_EXTENDED_SYS_STATE:{
293 mavlink_extended_sys_state_t mss;
294 mavlink_msg_extended_sys_state_decode(&message, &mss);
295 //inCopterData[4]=mss.vtol_state;
296 //inCopterData[5]=mss.landed_state;
297 if(mavState.landed_state!=mss.landed_state){
298 mavState.landed_state=mss.landed_state;
299 switch(mss.landed_state){
300 case MAV_LANDED_STATE_ON_GROUND:
301 std::cout<<"Drone #"<<CopterID<<": "<<"On ground."<<std::endl;
302 break;
303 case MAV_LANDED_STATE_IN_AIR:
304 std::cout<<"Drone #"<<CopterID<<": "<<"In air."<<std::endl;
305 break;
306 case MAV_LANDED_STATE_TAKEOFF:
307 std::cout<<"Drone #"<<CopterID<<": "<<"Takeoff."<<std::endl;
308 break;
309 case MAV_LANDED_STATE_LANDING:
310 std::cout<<"Drone #"<<CopterID<<": "<<"Landing."<<std::endl;
311 break;
312 }
313 }
314 break;
315 }
316
317 case MAVLINK_MSG_ID_LOCAL_POSITION_NED:{
318 mavlink_local_position_ned_t lpn;
319 mavlink_msg_local_position_ned_decode(&message, &lpn);
320 data.localPos[0]=lpn.x;
321 data.localPos[1]=lpn.y;
322 data.localPos[2]=lpn.z;
323 data.localVel[0] = lpn.vx;
324 data.localVel[1] = lpn.vy;
325 data.localVel[2] = lpn.vz;
326 data.time_boot_ms = lpn.time_boot_ms;
327
328 if(!mavState.isLocalNed){
329 mavState.isLocalNed=true;
330 std::cout<<"Drone #"<<CopterID<<": Got local pos x,y,z "<<data.localPos[0]<<","<<data.localPos[1]<<","<<data.localPos[2]<<","<<std::endl;
331 }
332
333 //isUpdate=true;
334
335 if(mavState.isGpsHome){
336 if(data.calcGlobalPos(GpsOrin)){
337 if(!mavState.isGlobPos){
338 mavState.isGlobPos=true;
339 std::cout<<"Drone #"<<CopterID<<": Got global pos x,y,z "<<data.GlobalPos[0]<<","<<data.GlobalPos[1]<<","<<data.GlobalPos[2]<<","<<std::endl;
340 }
341 }
342 }
343
344 break;
345 }
346 case MAVLINK_MSG_ID_ATTITUDE:{
347 mavlink_attitude_t att;
348 mavlink_msg_attitude_decode(&message, &att);
349 //data.time_boot_ms = RunnedTime;
350 //data.copterID = copterID;
351 data.AngEular[0]=att.roll;
352 data.AngEular[1]=att.pitch;
353 data.AngEular[2]=att.yaw;
354 data.AngRate[0]=att.rollspeed;
355 data.AngRate[1]=att.pitchspeed;
356 data.AngRate[2]=att.yawspeed;
357 data.time_boot_ms = att.time_boot_ms;
358 // if (!mavState.initYaw && currentTime > 1){
359 // mavState.yawOffset = mavState.yaw - data[5];
360 // cout <<"sysID: "<<(int)(mavState.sysID) <<"\tyawOffset: "<< mavState.yawOffset << endl;
361 // mavState.initYaw = true;
362 // }
363 //isUpdate=true;
364 break;
365 }
366 case MAVLINK_MSG_ID_BATTERY_STATUS:{
367 mavlink_battery_status_t bat;
368 mavlink_msg_battery_status_decode(&message, &bat);
369 mavState.batteryInfo[0] = (double)bat.battery_remaining;
370 break;
371 }
372 case MAVLINK_MSG_ID_GLOBAL_POSITION_INT:{
373 mavlink_global_position_int_t gp;
374 mavlink_msg_global_position_int_decode(&message, &gp);
375 //outHILStateData outHilData;
376 //data.time_boot_ms = gp.time_boot_ms;
377 //data.time_boot_ms = RunnedTime;
378 data.GpsPos[0]=gp.lat;
379 data.GpsPos[1]=gp.lon;
380 data.GpsPos[2]=gp.alt;
381 data.relative_alt = gp.relative_alt;
382 data.GpsVel[0]=gp.vx;
383 data.GpsVel[1]=gp.vy;
384 data.GpsVel[2]=gp.vz;
385 data.hdg = gp.hdg;
386 break;
387 }
388 case MAVLINK_MSG_ID_GPS_RAW_INT:{
389 //qDebug()<<"State Received!";
390 mavlink_gps_raw_int_t gri;
391 mavlink_msg_gps_raw_int_decode(&message, &gri);
392 //data.time_boot_ms = gri.time_usec;
393 data.fix_type = gri.fix_type;
394 //qDebug()<<data.fix_type;
395 data.satellites_visible = gri.satellites_visible;
396
397 break;
398 }
399 case MAVLINK_MSG_ID_ESTIMATOR_STATUS:{
400
401 //qDebug()<<"State Received!";
402 mavlink_estimator_status_t es;
403 mavlink_msg_estimator_status_decode(&message, &es);
404 //data.time_boot_ms = RunnedTime;
405 //data.time_boot_ms = es.time_usec;
406 data.pos_horiz_accuracy = es.pos_horiz_accuracy;
407 data.pos_vert_accuracy = es.pos_vert_accuracy;
408
409 //qDebug()<<"Status: "<<data.pos_horiz_accuracy<<","<<es.pos_horiz_ratio;
410 break;
411 }
412
413 case MAVLINK_MSG_ID_HOME_POSITION:{
414
415 //if(!m_flightModel.isSkipGps){
416 mavlink_home_position_t hm;
417 mavlink_msg_home_position_decode(&message, &hm);
418 data.gpsHome[0] = hm.latitude;
419 data.gpsHome[1] = hm.longitude;
420 data.gpsHome[2] = hm.altitude;
421 //data.time_boot_ms = RunnedTime;
422 mavState.isGpsHome=true;
423 break;
424 }
425 case MAVLINK_MSG_ID_STATUSTEXT:{
426 mavlink_statustext_t mavStatusText;
427 mavlink_msg_statustext_decode(&message, &mavStatusText);
428 std::string mystr(mavStatusText.text);
429 std::cout<<"Drone #"<<CopterID<<" STATUSTEXT: "<< mystr << std::endl;
430 stringToLower(mystr);
431 if (mystr.find("failsafe mode enabled") != std::string::npos) {
432 mavState.isFailSafeEn=true;
433 }
434 break;
435 }
436 case MAVLINK_MSG_ID_COMMAND_ACK:{
437 mavlink_command_ack_t mck;
438 mavlink_msg_command_ack_decode(&message, &mck);
439 std::string qstrt;
440
441 switch(mck.result){
442 case 0:
443 qstrt="ACCEPTED";
444 break;
445 case 1:
446 qstrt="TEMPORARILY_REJECTED";
447 break;
448 case 2:
449 qstrt="DENIED";
450 break;
451 case 3:
452 qstrt="UNSUPPORTED";
453 break;
454 case 4:
455 qstrt="FAILED";
456 break;
457 case 5:
458 qstrt="IN_PROGRESS";
459 break;
460 }
461
462 std::string cmdName;
463 switch(mck.command){
464 case 400:
465 cmdName = "ARM/DISARM";
466 break;
467 case 176:
468 cmdName = "SET_MODE";
469 break;
470 case 246:
471 cmdName = "REBOOT/SHUTDOWN";
472 break;
473 case 519:
474 cmdName = "REQUEST_MAVLINK_VERSION";
475 break;
476 case 520:
477 cmdName = "REQUEST_AUTOPILOT_VERSION";
478 break;
479 case 92:
480 cmdName = "NAV_GUIDED_ENABLE";
481 break;
482 case 21:
483 cmdName = "NAV_LAND";
484 break;
485 case 22:
486 cmdName = "NAV_TAKEOFF";
487 break;
488 case 192:
489 cmdName = "DO_REPOSITION";
490 break;
491 default:
492 cmdName = "ID: "+ std::to_string(mck.command);
493 break;
494 }
495
496 std::cout<<"Drone #"<<CopterID<<": "<<"Command "<<cmdName<<" "<<qstrt<<std::endl;
497 break;
498 }
499
500
501 }
502 }
503
504
505 void stringToLower(std::string& str)
506 {
507 std::transform(str.begin(), str.end(), str.begin(), [](char& c){
508 return std::tolower(c);
509 });
510 }
511
512 void SendMsg(mavlink_message_t mess){
513 unsigned int length = mavlink_msg_to_send_buffer((uint8_t*)buf, &mess);
514 if(length>0){
515 buf[length]='0';
516 udp.SendTo((const char *)buf,length,TargetIP,TargetPort);
517 }
518
519 }
520
521 void SendHeartbeat(){
522 mavlink_message_t mess;
523 mavlink_heartbeat_t MavHartt;
524 MavHartt.autopilot = MAV_AUTOPILOT_INVALID;
525 MavHartt.base_mode = 0;
526 MavHartt.custom_mode = 0;
527 MavHartt.system_status = MAV_STATE_ACTIVE;
528 MavHartt.type = MAV_TYPE_GCS;
529 mavlink_msg_heartbeat_encode(mavState.sysID, mavState.compID, &mess, &MavHartt);
530 SendMsg(mess);
531 }
532
533 void SendMavCmdLong(uint16_t command, float param1, float param2=0, float param3=0,float param4=0,float param5=0,float param6=0,float param7=0)
534 {
535 mavlink_message_t mess;
536 mavlink_command_long_t command_long;
537 command_long.target_system = mavState.TargetSysID;
538 command_long.target_component = mavState.TargetCompID;
539 command_long.confirmation = 0;
540 command_long.command = command;
541 command_long.param1 = param1;
542 command_long.param2 = param2;
543 command_long.param3 = param3;
544 command_long.param4 = param4;
545 command_long.param5 = param5;
546 command_long.param6 = param6;
547 command_long.param7 = param7;
548 mavlink_msg_command_long_encode(mavState.sysID, mavState.compID, &mess, &command_long);
549 SendMsg(mess);
550 }
551
552
553 void SendMavArm(int isArm)
554 {
555 // arm
556 if (isArm) {
557 SendMavCmdLong(MAV_CMD_COMPONENT_ARM_DISARM, 1);
558 }
559 // disarm
560 else {
561 SendMavCmdLong(MAV_CMD_COMPONENT_ARM_DISARM, 0, 21196.0f);
562 }
563 }
564
565 // Send MAVLink command to PX4 to change flight mode
566 // https://mavlink.io/en/messages/common.html#MAV_CMD_DO_SET_MODE
567 void SendSetMode(int mainMode, int customMode=0)
568 {
569 uint16_t baseMode = MAV_MODE_FLAG_MANUAL_INPUT_ENABLED | MAV_MODE_FLAG_CUSTOM_MODE_ENABLED;
570 SendMavCmdLong(MAV_CMD_DO_SET_MODE, baseMode, mainMode, customMode);
571 }
572
573 void SendPositionTarget(uint16_t type_mask, uint8_t coordinate, float *data){
574 mavlink_message_t mess;
575 if (coordinate == MAV_FRAME_LOCAL_NED) {
576 mavlink_set_position_target_local_ned_t m_target_ned;
577 //m_target_ned.time_boot_ms = SGetCurrentTime();
578 m_target_ned.target_system = mavState.TargetSysID;
579 m_target_ned.target_component = mavState.TargetCompID;
580 m_target_ned.coordinate_frame = coordinate;
581 m_target_ned.type_mask = type_mask;
582 m_target_ned.x = data[0];
583 m_target_ned.y = data[1];
584 // from vision frame to ned
585 m_target_ned.z = data[2];
586 m_target_ned.vx = data[3];
587 m_target_ned.vy = data[4];
588 // from vision frame to ned
589 m_target_ned.vz = data[5];
590 m_target_ned.afx = data[6];
591 m_target_ned.afy = data[7];
592 // from vision frame to ned
593 m_target_ned.afz = data[8];
594 m_target_ned.yaw = data[11];
595 // from vision frame to ned
596 m_target_ned.yaw_rate = data[14];
597 // from vision frame to ned
598 // mavState.rotate(m_target_ned.x, m_target_ned.y);
599 // mavState.rotate(m_target_ned.vx, m_target_ned.vy);
600 // mavState.rotate(m_target_ned.afx, m_target_ned.afy);
601
602 mavlink_msg_set_position_target_local_ned_encode(mavState.sysID, mavState.compID, &mess, &m_target_ned);
603 }
604 else if (coordinate == MAV_FRAME_GLOBAL_INT){
605 mavlink_set_position_target_global_int_t m_target_global;
606 //m_target_global.time_boot_ms = SGetCurrentTime();
607 m_target_global.target_system = mavState.TargetSysID;
608 m_target_global.target_component = mavState.TargetCompID;
609 m_target_global.coordinate_frame = coordinate;
610 m_target_global.type_mask = type_mask;
611 m_target_global.lat_int = (int32_t)(data[0]*1e7);
612 m_target_global.lon_int = (int32_t)(data[1]*1e7);
613 m_target_global.alt = data[2];
614 m_target_global.vx = data[3];
615 m_target_global.vy = data[4];
616 m_target_global.vz = data[5];
617 m_target_global.afx = data[6];
618 m_target_global.afy = data[7];
619 m_target_global.afz = data[8];
620 m_target_global.yaw = data[11];
621 m_target_global.yaw_rate = data[14];
622 mavlink_msg_set_position_target_global_int_encode(mavState.sysID, mavState.compID, &mess, &m_target_global);
623 }
624 SendMsg(mess);
625 }
626
627
628 void SendAttitudeTarget(uint8_t type_mask, float *data){
629 mavlink_message_t mess;
630 mavlink_set_attitude_target_t m_target_att;
631 //m_target_att.time_boot_ms = SGetCurrentTime();
632 m_target_att.target_system = mavState.TargetSysID;
633 m_target_att.target_component = mavState.TargetCompID;
634 m_target_att.type_mask = type_mask;
635
636 float roll = data[9];
637 float pitch = data[10];
638 float yaw = data[11];
639 float sp2 = sin(pitch/2);
640 float sy2 = sin(yaw/2);
641 float cr2 = cos(roll/2);
642 float cp2 = cos(pitch/2);
643 float cy2 = cos(yaw/2);
644 float sr2 = sin(roll/2);
645
646 float qx = sp2*sy2*cr2+cp2*cy2*sr2;
647 float qy = sp2*cy2*cr2+cp2*sy2*sr2;
648 float qz = cp2*sy2*cr2-sp2*cy2*sr2;
649 float qw = cp2*cy2*cr2-sp2*sy2*sr2;
650
651 m_target_att.q[0] = qw;
652 m_target_att.q[1] = qx;
653 m_target_att.q[2] = qy;
654 m_target_att.q[3] = qz;
655 m_target_att.body_roll_rate = data[12];
656 m_target_att.body_pitch_rate = data[13];
657 m_target_att.body_yaw_rate = data[14];
658 m_target_att.thrust = data[15];
659 mavlink_msg_set_attitude_target_encode(mavState.sysID, mavState.compID, &mess, &m_target_att);
660 SendMsg(mess);
661 }
662
663 void SendParamInt(std::string id, int value){
664 mavlink_message_t mess;
665 mavlink_param_set_t param;
666
667 param.target_system = mavState.TargetSysID;
668 param.target_component = mavState.TargetCompID;
669 param.param_value = float(value)/7.13622e+44; // A Change is required.
670 param.param_type = MAV_PARAM_TYPE_INT32;
671 strcpy(param.param_id, id.c_str());
672
673 mavlink_msg_param_set_encode(mavState.sysID, mavState.compID, &mess, &param);
674 SendMsg(mess);
675 }
676
677 void SendParamFloat(std::string id, float value){
678 mavlink_message_t mess;
679 mavlink_param_set_t param;
680
681 param.target_system = mavState.TargetSysID;
682 param.target_component = mavState.TargetCompID;
683 param.param_value = value;
684 param.param_type = MAV_PARAM_TYPE_REAL32;
685 strcpy(param.param_id, id.c_str());
686
687 mavlink_msg_param_set_encode(mavState.sysID, mavState.compID, &mess, &param);
688 SendMsg(mess);
689 }
690
691 void SendRccTarget(float *data)
692 {
693 mavlink_message_t mess;
694 mavlink_rc_channels_override_t rcc;
695 uint16_t middle_rc = 1500;
696
697 rcc.target_system = mavState.TargetSysID;
698 rcc.target_component = mavState.TargetCompID;
699 rcc.chan1_raw = (uint16_t)data[13];
700 rcc.chan2_raw = (uint16_t)data[14];
701 rcc.chan3_raw = (uint16_t)data[16];
702 rcc.chan4_raw = (uint16_t)data[15];
703 //cout << rcc.chan1_raw <<"\t" << rcc.chan3_raw << endl;
704 rcc.chan5_raw = middle_rc;
705 rcc.chan6_raw = middle_rc;
706 rcc.chan7_raw = middle_rc;
707 rcc.chan8_raw = middle_rc;
708 mavlink_msg_rc_channels_override_encode(mavState.sysID, mavState.compID, &mess, &rcc);
709
710 SendMsg(mess);
711
712 mavlink_manual_control_t manual;
713 manual.target = mavState.sysID;
714 manual.x = (rcc.chan2_raw-1500)*2;
715 manual.y = (rcc.chan1_raw-1500)*2;
716 manual.z = rcc.chan3_raw-1000;
717 manual.r = (rcc.chan4_raw-1500)*2;
718 manual.buttons = 0;
719 mavlink_msg_manual_control_encode(mavState.sysID, mavState.compID, &mess, &manual);
720 SendMsg(mess);
721 }
722
723
724
725 void SendVisionPosition(uint64_t time_usec, float x, float y, float z, float roll, float pitch, float yaw)
726 {
727 mavlink_message_t mess;
728 mavlink_vision_position_estimate_t vision_position;
729 vision_position.usec = time_usec;
730 vision_position.x = x;
731 vision_position.y = y;
732 vision_position.z = z;
733 vision_position.roll = roll;
734 vision_position.pitch = pitch;
735 vision_position.yaw = yaw;
736
737 mavlink_msg_vision_position_estimate_encode(mavState.sysID, mavState.compID, &mess, &vision_position);
738 //std::cout<<std::to_string(time_usec)<<", "<<std::to_string(mavState.sysID)<<", "<<std::to_string(mavState.compID)<<", "<<std::to_string(mess.len)<<", "<<std::to_string(mess.seq)<<", "<<vision_position.x<<", "<<vision_position.y<<", "<<vision_position.z<<", "<<vision_position.yaw<<std::endl;
739 SendMsg(mess);
740 }
741
742
743 // y0 -> Time stamp sec for pos msg
744 // y1 -> Time stamp usec for pos msg
745 // t_pos_msg = y0 + y1 / 1000000.0
746 // y2-y4 -> Pos_x,Pos_y,Pos_z in ned, unit m
747 // y5-y8 -> Quat (w,x,y,z) for vehicle attitude
748 // y9 -> Time stamp sec for vel msg
749 // y10 -> Time stamp usec for vel msg
750 // t_vel_msg = y9 + y10 / 1000000.0
751 // y11-y13 -> vel_x,vel_y,vel_z in ned, unit m/s
752 // y14 -> Time stamp sec for acc msg
753 // y15 -> Time stamp usec for acc msg
754 // y16-y18 -> acc_x,acc_y,acc_z in ned, unit m/s^2
755 // y19-y21 -> Euler (roll pitch yaw) ang from vehicle Quat
756 // y22 -> tracker->has_data, is there any vrpn message received.
757 // y23 -> tracker->has_pos, is the vrpn pos message received.
758 // 24-29 -> reserve for future use
759 void Send3DShow(double y[30])
760 {
761 SOut2Simulator m_show3d;
762 uint64_t time_usec = y[0]*1000000+y[1];
763 if(m_start_time==0){
764 m_start_time=time_usec;
765 }
766 double runTime = (time_usec-m_start_time)/1000000.0; // 时间戳
767 m_show3d.checksum=123456789;
768 m_show3d.copterID = CopterID;
769 m_show3d.runnedTime = runTime;
770 m_show3d.vehicleType = 600251; // 显示飞机
771 for (int i = 0; i < 3; i++) {
772 m_show3d.PosE[i] = y[2+i];
773 m_show3d.AngEuler[i] = y[19+i];
774 m_show3d.VelE[i]= y[11+i];
775 m_show3d.PosGPS[i]=0;
776 m_show3d.RateB[i]=0;
777 m_show3d.AccB[i]=y[16+i];
778 m_show3d.AngQuatern[i]=y[5+i];
779 }
780 m_show3d.AngQuatern[3]=y[8];
781
782 // 仿真超过1s,且高度大于0.2,才开启螺旋桨
783 if(m_show3d.runnedTime>1 && m_show3d.PosE[2]<-0.1){
784 for (int i = 0; i < 4; i++) {
785 m_show3d.MotorRPMS[i] = 500; //单位RPM
786 m_show3d.MotorRPMS[4+i] = 0;
787 }
788 }
789
790 // 发送到RflySim3D用于三维显示
791 udp.SendTo((const char *)&m_show3d,sizeof(m_show3d),"127.0.0.1",20010);
792
793 }
794
795
796 // void SendVisionOdometry(uint64_t time_usec, float pos[3],float vel[3],float quat[4],float rate[3], bool isReset=false)
797 // {
798 // mavlink_message_t mess;
799 // mavlink_odometry_t odo;
800
801 // static int resetCont=0;
802
803 // /**
804 // * PX4 expects the body's linear velocity in the local frame,
805 // * the linear velocity is rotated from the odom child_frame to the
806 // * local NED frame. The angular velocity needs to be expressed in the
807 // * body (fcu_frd) frame.
808 // */
809 // uint8_t frame_id=MAV_FRAME_LOCAL_FRD;
810
811
812 // /**
813 // * Supported local frame of reference is MAV_FRAME_LOCAL_NED or MAV_FRAME_LOCAL_FRD
814 // * The supported sources of the data/tesimator type are MAV_ESTIMATOR_TYPE_VISION,
815 // * MAV_ESTIMATOR_TYPE_VIO and MAV_ESTIMATOR_TYPE_MOCAP
816 // *
817 // * @note Regarding the local frames of reference, the appropriate EKF_AID_MASK
818 // * should be set in order to match a frame aligned (NED) or not aligned (FRD)
819 // * with true North
820 // */
821 // uint8_t child_frame_id=MAV_FRAME_LOCAL_FRD;
822
823 // odo.time_usec = time_usec;
824 // odo.x=pos[0];/*< [m] X Position*/
825 // odo.y=pos[1];/*< [m] Y Position*/
826 // odo.z=pos[2];/*< [m] Z Position*/
827
828 // for(int i=0;i<4;i++){
829 // odo.q[i]=quat[i]; /*< Quaternion components, w, x, y, z (1 0 0 0 is the null-rotation)*/
830 // }
831
832 // odo.vx=vel[0]; /*< [m/s] X linear speed*/
833 // odo.vy=vel[1]; /*< [m/s] Y linear speed*/
834 // odo.vz=vel[2]; /*< [m/s] Z linear speed*/
835
836 // odo.rollspeed=rate[0]; /*< [rad/s] Roll angular speed*/
837 // odo.pitchspeed=rate[1]; /*< [rad/s] Pitch angular speed*/
838 // odo.yawspeed=rate[2]; /*< [rad/s] Yaw angular speed*/
839
840 // float covariance[21]={0};
841 // covariance[0]=NAN; //set NAN to disable pose_covariance
842
843 // odo.estimator_type=MAV_ESTIMATOR_TYPE_VIO;
844
845 // if(isReset){ //self add if need reset.
846 // resetCont++;
847 // }
848 // odo.reset_counter=resetCont;
849
850 // mavlink_msg_odometry_encode(mavState.sysID, mavState.compID, &mess, &odo);
851 // SendMsg(mess);
852 // }
853
854 void setFlightMode_px4(PX4_FLIGHTMODE newMode, uint32_t& outCustomMode){
855 px4_custom_mode outdata;
856 outdata.data = 0;
857 switch (newMode)
858 {
859 case PX4_FLIGHTMODE_MANUAL:
860 outdata.main_mode = PX4_CUSTOM_MAIN_MODE_MANUAL;
861 outdata.sub_mode = 0;
862 break;
863 case PX4_FLIGHTMODE_ALT:
864 outdata.main_mode = PX4_CUSTOM_MAIN_MODE_ALTCTL;
865 outdata.sub_mode = 0;
866 break;
867 case PX4_FLIGHTMODE_POS:
868 outdata.main_mode = PX4_CUSTOM_MAIN_MODE_POSCTL;
869 outdata.sub_mode = 0;
870 break;
871 case PX4_FLIGHTMODE_TAKEOFF:
872 outdata.main_mode = PX4_CUSTOM_MAIN_MODE_AUTO;
873 outdata.sub_mode = PX4_CUSTOM_SUB_MODE_AUTO_TAKEOFF;
874 break;
875 case PX4_FLIGHTMODE_LAND:
876 outdata.main_mode = PX4_CUSTOM_MAIN_MODE_AUTO;
877 outdata.sub_mode = PX4_CUSTOM_SUB_MODE_AUTO_LAND;
878 break;
879 case PX4_FLIGHTMODE_MISSION:
880 outdata.main_mode = PX4_CUSTOM_MAIN_MODE_AUTO;
881 outdata.sub_mode = PX4_CUSTOM_SUB_MODE_AUTO_MISSION;
882 break;
883 case PX4_FLIGHTMODE_RTL:
884 outdata.main_mode = PX4_CUSTOM_MAIN_MODE_AUTO;
885 outdata.sub_mode = PX4_CUSTOM_SUB_MODE_AUTO_RTL;
886 break;
887
888 case PX4_FLIGHTMODE_STABILIZED:
889 outdata.main_mode = PX4_CUSTOM_MAIN_MODE_STABILIZED;
890 outdata.sub_mode = 0;
891 break;
892
893 case PX4_FLIGHTMODE_OFFBOARD:
894 outdata.main_mode = PX4_CUSTOM_MAIN_MODE_OFFBOARD;
895 outdata.sub_mode = 0;
896 break;
897
898 case PX4_FLIGHTMODE_AUTO_READY:
899 outdata.main_mode = PX4_CUSTOM_MAIN_MODE_AUTO;
900 outdata.sub_mode = PX4_CUSTOM_SUB_MODE_AUTO_LOITER;
901 break;
902
903 case PX4_FLIGHTMODE_AUTO_LOITER:
904 outdata.main_mode = PX4_CUSTOM_MAIN_MODE_AUTO;
905 outdata.sub_mode = PX4_CUSTOM_SUB_MODE_AUTO_LOITER;
906 break;
907
908 default:
909 break;
910 }
911 outCustomMode = outdata.data;
912 }
913
914 void getFlightMode_px4(uint32_t inCustomMode, PX4_FLIGHTMODE& outMode){
915 px4_custom_mode indata;
916 indata.data = inCustomMode;
917 //qDebug()<<inCustomMode<<indata.main_mode<<indata.sub_mode;
918 if (indata.main_mode == PX4_CUSTOM_MAIN_MODE_MANUAL){
919 outMode = PX4_FLIGHTMODE_MANUAL;
920 }
921 else if (indata.main_mode == PX4_CUSTOM_MAIN_MODE_ALTCTL){
922 outMode = PX4_FLIGHTMODE_ALT;
923 }
924 else if (indata.main_mode == PX4_CUSTOM_MAIN_MODE_POSCTL){
925 outMode = PX4_FLIGHTMODE_POS;
926 }
927 else if (indata.main_mode == PX4_CUSTOM_MAIN_MODE_OFFBOARD){
928 outMode = PX4_FLIGHTMODE_OFFBOARD;
929 }
930 else if (indata.main_mode == PX4_CUSTOM_MAIN_MODE_STABILIZED){
931 outMode = PX4_FLIGHTMODE_STABILIZED;
932 }
933 else if (indata.main_mode == PX4_CUSTOM_MAIN_MODE_AUTO)
934 {
935 if (indata.sub_mode == PX4_CUSTOM_SUB_MODE_AUTO_MISSION){
936 outMode = PX4_FLIGHTMODE_MISSION;
937 }
938 else if (indata.sub_mode == PX4_CUSTOM_SUB_MODE_AUTO_TAKEOFF){
939 outMode = PX4_FLIGHTMODE_TAKEOFF;
940 }
941 else if (indata.sub_mode == PX4_CUSTOM_SUB_MODE_AUTO_LAND){
942 outMode = PX4_FLIGHTMODE_LAND;
943 }
944 else if (indata.sub_mode == PX4_CUSTOM_SUB_MODE_AUTO_RTL){
945 outMode = PX4_FLIGHTMODE_RTL;
946 }
947 else if (indata.sub_mode == PX4_CUSTOM_SUB_MODE_AUTO_READY){
948 outMode = PX4_FLIGHTMODE_AUTO_READY;
949 }
950 else if (indata.sub_mode == PX4_CUSTOM_SUB_MODE_AUTO_LOITER){
951 outMode = PX4_FLIGHTMODE_AUTO_LOITER;
952 }
953 }
954 }
955
956 std::string getFlightModeName_px4(PX4_FLIGHTMODE fm){
957
958 std::string qstr="";
959 switch (fm)
960 {
961 case 1:
962 qstr="Manual Mode";
963 break;
964 case 2:
965 qstr="Altitude Mode";
966 break;
967 case 3:
968 qstr="Position Mode";
969 break;
970 case 4:
971 qstr="Takeoff Mode";
972 break;
973 case 5:
974 qstr="Land Mode";
975 break;
976 case 6:
977 qstr="Auto Mode";
978 break;
979 case 7:
980 qstr="RTL Mode";
981 break;
982 case 8:
983 qstr="Stablized Mode";
984 break;
985 case 9:
986 qstr="Offboard Mode";
987 break;
988 case 10:
989 qstr="Auto Ready Mode";
990 break;
991 case 11:
992 qstr="Auto Loiter Mode";
993 break;
994 default:
995 qstr="Other Mode";
996 break;
997 }
998 return qstr;
999
1000 }
1001
1002 bool isBitTrue(uint32_t value, int bitIndex) {
1003 return (value & (1U << bitIndex)) != 0;
1004 }
1005
1006 // input vector, input dim, sim time (s)
1007 void SendMavlinkFull(double **u, double t){
1008
1009 if(offCtrlState==0){
1010 SendVelNED(0,0,0,0);
1011 offLastTime=t;
1012 offCtrlState=1;
1013 }
1014 if(offCtrlState==1){
1015 SendVelNED(0,0,0,0);
1016 if(t-offLastTime>1.1){
1017 sendMavEnableGuided(true);
1018 offLastTime=t;
1019 offCtrlState=2;
1020 }
1021 }
1022 if(offCtrlState==2){
1023 if(t-offLastTime>1.1){
1024 SendMavArm(true);
1025 offCtrlState=3;
1026 }
1027 }
1028 if(offCtrlState==3){
1029
1030 inHILCMDData hil;
1031 //inData.time_boot_ms = 123;
1032 hil.time_boot_ms = (uint32_t)*u[0];
1033 hil.copterID=(uint32_t)*u[1];
1034 hil.modes=(uint32_t)*u[2];
1035 hil.flags=(uint32_t)*u[3];
1036 for(int j=0;j<11;j++){
1037 hil.ctrls[j]=(float)*u[4+j];
1038 }
1039 uint16_t type_mask = hil.modes & 0xFFF;
1040 uint8_t coordinate_frame = hil.flags & 0xFF;
1041 sendMavOffboardCmd(type_mask,coordinate_frame,hil.ctrls[0],hil.ctrls[1],hil.ctrls[2],hil.ctrls[3],hil.ctrls[4],hil.ctrls[5],hil.ctrls[6],hil.ctrls[7],hil.ctrls[8],hil.ctrls[9],hil.ctrls[10]);
1042
1043 }
1044
1045 }
1046
1047
1048 // input vector, input dim, sim time (s)
1049 void SendMavlinkSimple(double **u, double t){
1050
1051 if(offCtrlState==0){
1052 SendVelNED(0,0,0,0);
1053 offLastTime=t;
1054 offCtrlState=1;
1055 }
1056 if(offCtrlState==1){
1057 SendVelNED(0,0,0,0);
1058 if(t-offLastTime>1.1){
1059 sendMavEnableGuided(true);
1060 offLastTime=t;
1061 offCtrlState=2;
1062 }
1063 }
1064 if(offCtrlState==2){
1065 if(t-offLastTime>1.1){
1066 SendMavArm(true);
1067 offCtrlState=3;
1068 }
1069 }
1070 if(offCtrlState==3){
1071 int ctrlMode=(int)*u[0];
1072 float ctrls[4];
1073
1074 if(ctrlMode <0){ // no Data send mode
1075 return;
1076 }
1077
1078 // the input len is numIn
1079 for(int j=0; j<4; j++){ // numIn-2 for controls
1080 ctrls[j] = (float)*u[1+j];
1081 }
1082
1083 SendOffSimp(ctrlMode,ctrls);
1084 }
1085
1086 }
1087
1088 // idx=0 1 2 for rfly_ctrl rfly_ctrl1 rfly_ctrl2 msg to Simulink Controller
1089 // u[1], flags, related to isEnCtrl
1090 // u[2], mode, related to idx
1091 // u[8-23], controls, total 16 elements
1092 // The meaning of u[1], u[8-23] can be user defined
1093 void sendHILCtrlMessage(double **u, double t)
1094 {
1095 uint8_t modes=1;
1096 uint64_t flags=(uint64_t)*u[1];
1097 double idx=(double)*u[2];
1098 if(idx<0.5){
1099 modes=1; // for rfly_ctrl msg
1100 }else if(idx<1.5){
1101 modes=101; // for rfly_ctrl1 msg
1102 }else{
1103 modes=201; // for rfly_ctrl2 msg
1104 }
1105
1106 mavlink_hil_actuator_controls_t hilctrl;
1107 hilctrl.mode = modes;
1108 hilctrl.flags = flags;
1109 for(int i=0;i<16;i++){
1110 hilctrl.controls[i]=(float)*u[i+8];
1111 }
1112 mavlink_message_t mess;
1113 mavlink_msg_hil_actuator_controls_encode(mavState.sysID, mavState.compID, &mess, &hilctrl);
1114 SendMsg(mess);
1115 }
1116
1117
1118 // input vector, input dim, sim time (s)
1119 void SendMavlinkReal(double **u, double t){
1120
1121 inRealflyData ird;
1122 ird.cmdBitmap = (uint32_t)*u[1];
1123 ird.typeMask = (uint16_t)*u[2];
1124
1125 // the input len is numIn
1126 for(int j=0; j<20; j++){ // numIn-8 for controls
1127 ird.controls[j] = (float)*u[8+j];
1128 }
1129
1130 //
1131 if (isBitTrue(ird.cmdBitmap, 0)){
1132 //
1133 if (isBitTrue(ird.cmdBitmap, 2))
1134 SendMavArm(1);
1135 else if (isBitTrue(ird.cmdBitmap, 7))
1136 SendMavArm(0);
1137
1138 // Offboard
1139 if (isBitTrue(ird.cmdBitmap, 3)){
1140 SendSetMode(PX4_CUSTOM_MAIN_MODE_OFFBOARD);
1141 }
1142 // Mannual
1143 if (isBitTrue(ird.cmdBitmap, 28)){
1144 SendSetMode(PX4_CUSTOM_MAIN_MODE_MANUAL);
1145 }
1146 // Alt
1147 if (isBitTrue(ird.cmdBitmap, 29)){
1148 SendSetMode(PX4_CUSTOM_MAIN_MODE_ALTCTL);
1149 }
1150 // Position
1151 if (isBitTrue(ird.cmdBitmap, 30)){
1152 SendSetMode(PX4_CUSTOM_MAIN_MODE_POSCTL);
1153 }
1154 // AUTO
1155 if (isBitTrue(ird.cmdBitmap, 31)) {
1156 SendSetMode(MAV_MODE_FLAG_AUTO_ENABLED, PX4_CUSTOM_SUB_MODE_AUTO_LOITER);
1157 }
1158 }
1159
1160 // send Offboard
1161 if (isBitTrue(ird.cmdBitmap, 16)) {
1162 uint8_t coordinate = MAV_FRAME_LOCAL_NED;
1163 if (isBitTrue(ird.cmdBitmap, 18))
1164 coordinate = MAV_FRAME_GLOBAL_INT;
1165 else if (isBitTrue(ird.cmdBitmap, 19))
1166 coordinate = MAV_FRAME_BODY_NED;
1167 SendPositionTarget(ird.typeMask, coordinate, ird.controls);
1168 }
1169 else if (isBitTrue(ird.cmdBitmap, 17)){
1170 SendAttitudeTarget(ird.typeMask, ird.controls);
1171 }
1172 else if (isBitTrue(ird.cmdBitmap, 23)){
1173 if (!isRcc){
1174 SendParamInt("NAV_RCL_ACT", 0);
1175 SendParamInt("NAV_DLL_ACT", 0);
1176 isRcc = true;
1177 SendSetMode(PX4_CUSTOM_MAIN_MODE_MANUAL);
1178 }
1179 SendRccTarget(ird.controls);
1180 }
1181
1182 }
1183
1184 void mavlinkSetCmd(uint16_t command,float param1=0,float param2=0,float param3=0){
1185 SendMavCmdLong(command,param1,param2,param3);
1186 }
1187
1188 void sendMavSetParam(char param_id[], float param_value, MAV_PARAM_TYPE param_type)
1189 {
1190
1191 mavlink_param_set_t ps;
1192 ps.target_system = mavState.TargetSysID;
1193 ps.target_component = mavState.TargetCompID;
1194 ps.param_value = param_value;
1195 ps.param_type = param_type;
1196 for(int i=0;i<16;i++){
1197 ps.param_id[i] = param_id[i];
1198 }
1199 mavlink_message_t mess;
1200 mavlink_msg_param_set_encode(mavState.sysID, mavState.compID, &mess, &ps);
1201
1202 }
1203
1204
1205 void sendMavEnableGuided(bool isEnable)
1206 {
1207 if(isEnable){
1208 setMavModel(PX4_CUSTOM_MAIN_MODE_OFFBOARD);
1209 char cmd[17] = "NAV_RCL_ACT";
1210 sendMavSetParam(cmd,0,MAV_PARAM_TYPE_INT32);
1211 char cmd1[17] = "NAV_DLL_ACT";
1212 sendMavSetParam(cmd1,0,MAV_PARAM_TYPE_INT32);
1213 char cmd2[17] = "COM_RCL_EXCEPT";
1214 sendMavSetParam(cmd2,4/7.1362e+44,MAV_PARAM_TYPE_INT32);
1215 }else{
1216 //mavlinkSetCmd(MAV_CMD_NAV_GUIDED_ENABLE,false);
1217 setMavModel(PX4_CUSTOM_MAIN_MODE_MANUAL);
1218 }
1219 }
1220 void setMavModel(PX4_CUSTOM_MAIN_MODE mianMode){
1221 uint8_t basemode=static_cast<uint8_t>(MAV_MODE_FLAG::MAV_MODE_FLAG_CUSTOM_MODE_ENABLED);
1222
1223 mavlinkSetCmd(MAV_CMD_DO_SET_MODE,basemode,mianMode);
1224 }
1225
1226 void setMavModel(PX4_CUSTOM_MAIN_MODE mianMode,PX4_CUSTOM_SUB_MODE_AUTO custMode){
1227 uint8_t basemode=static_cast<uint8_t>(MAV_MODE_FLAG::MAV_MODE_FLAG_CUSTOM_MODE_ENABLED);
1228 mavlinkSetCmd(MAV_CMD_DO_SET_MODE,basemode,mianMode,custMode);
1229 }
1230
1231 void sendMavOffboardCmd(uint16_t type_mask, uint8_t coordinate_frame, float x, float y, float z, float vx, float vy, float vz, float afx, float afy, float afz, float yaw, float yaw_rate)
1232 {
1233 mavlink_set_position_target_local_ned_t m_target_ned;
1234 //m_target_ned.time_boot_ms = QDateTime::currentDateTime().currentMSecsSinceEpoch();
1235 m_target_ned.target_system = mavState.TargetSysID;
1236 m_target_ned.target_component = mavState.TargetCompID;
1237 m_target_ned.coordinate_frame = coordinate_frame;
1238 m_target_ned.type_mask = type_mask;
1239 m_target_ned.x = x;
1240 m_target_ned.y = y;
1241 m_target_ned.z = z;
1242 m_target_ned.vx = vx;
1243 m_target_ned.vy = vy;
1244 m_target_ned.vz = vz;
1245 m_target_ned.afx = afx;
1246 m_target_ned.afy = afy;
1247 m_target_ned.afz = afz;
1248 m_target_ned.yaw = yaw;
1249 m_target_ned.yaw_rate = yaw_rate;
1250
1251 mavlink_message_t mess;
1252 mavlink_msg_set_position_target_local_ned_encode(mavState.sysID, mavState.compID, &mess, &m_target_ned);
1253 SendMsg(mess);
1254 }
1255
1256
1257 void SendOffSimp(int ctrlMode,float controls[4]={0}){
1258 float ctrls[11] = {0};
1259 uint8_t coordinate_frame = 0;
1260 uint16_t type_mask = 0;
1261 switch (ctrlMode)
1262 {
1263 case 0: // Earth vel Ctrl
1264 coordinate_frame = MAV_FRAME_LOCAL_NED;
1265 type_mask = 7 | 7 << 6 | 1 << 10;
1266 ctrls[3] = controls[0];
1267 ctrls[4] = controls[1];
1268 ctrls[5] = controls[2];
1269 ctrls[10] = controls[3];
1270 break;
1271 case 1: //body vel ctrl
1272 coordinate_frame = MAV_FRAME_BODY_NED;
1273 type_mask = 7 | 7 << 6 | 1 << 10;
1274 ctrls[3] = controls[0];
1275 ctrls[4] = controls[1];
1276 ctrls[5] = controls[2];
1277 ctrls[10] = controls[3];
1278 break;
1279
1280 case 2: // earth pos ctrl
1281 coordinate_frame = MAV_FRAME_LOCAL_NED;
1282 type_mask = 7 << 3 | 7 << 6 | 1 << 11;
1283 ctrls[0] = controls[0];
1284 ctrls[1] = controls[1];
1285 ctrls[2] = controls[2];
1286 ctrls[9] = controls[3];
1287 break;
1288 case 3: // body pos ctrl
1289 coordinate_frame = MAV_FRAME_BODY_NED;
1290 type_mask = 7 << 3 | 7 << 6 | 1 << 11;
1291 ctrls[0] = controls[0];
1292 ctrls[1] = controls[1];
1293 ctrls[2] = controls[2];
1294 ctrls[9] = controls[3];
1295 break;
1296
1297 case 6: // body pos ctrl
1298 coordinate_frame = MAV_FRAME_LOCAL_NED;
1299 type_mask = 7 | 7 << 3 | 1 << 10 | 1 << 11;
1300 ctrls[6] = controls[0];
1301 ctrls[7] = controls[1];
1302 ctrls[8] = controls[2];
1303 break;
1304
1305 case 7: //
1306 coordinate_frame = MAV_FRAME_LOCAL_NED;
1307 type_mask = 7 | 7 << 3 | 1 << 11;
1308 ctrls[6] = controls[0];
1309 ctrls[7] = controls[1];
1310 ctrls[8] = controls[2];
1311 ctrls[9] = controls[3];
1312 break;
1313
1314 case 8: //
1315 coordinate_frame = MAV_FRAME_LOCAL_NED;
1316 type_mask = 7 | 7 << 3 | 1 << 10;
1317 ctrls[6] = controls[0];
1318 ctrls[7] = controls[1];
1319 ctrls[8] = controls[2];
1320 ctrls[10] = controls[3];
1321 break;
1322
1323 case 13:
1324 {
1325 coordinate_frame = 1;
1326 type_mask = 448;
1327 float vel = controls[0];
1328 float alt = controls[1];
1329 float yaw = controls[2];
1330
1331 ctrls[2] = alt;
1332 ctrls[3] = yaw;
1333 ctrls[4] = vel;
1334 break;
1335 }
1336
1337 default:
1338 break;
1339 }
1340
1341 sendMavOffboardCmd(type_mask,coordinate_frame,ctrls[0],ctrls[1],ctrls[2],ctrls[3],ctrls[4],ctrls[5],ctrls[6],ctrls[7],ctrls[8],ctrls[9],ctrls[10]);
1342
1343 }
1344
1345 void SendVelNED(float vx=0,float vy=0,float vz=0,float yawrate=0){
1346 float ctrls[4]={vx,vy,vz,yawrate};
1347 SendOffSimp(0,ctrls);
1348 }
1349
1350 // Self check program...
1351 bool SelfCheckProgram(double t){
1352 //std::cout<<"checking"<<std::endl;
1353 //-1:faild, 0 inited, 2. get local pos, 3. can offboard, 4. can armed, 5. checkPassed
1354
1355 // Send this can get px4 info for any valid local ip.
1356 // if (t-lastHeartbeatTime >= 1) {
1357 // SendHeartbeat();
1358 // lastHeartbeatTime = t;
1359 // }
1360 if((SelfCheckMainState==0) && t>2){ //Connection check
1361 if(mavState.isHeartRec){
1362 std::cout<<"Drone #"<<CopterID<<": Checking mavlink connection successfully."<<std::endl;
1363 mavState.selfCheckState=1;
1364 SelfCheckMainState=1; //go to mode 1.
1365 }
1366 }
1367
1368 if(SelfCheckMainState==1){
1369 if(mavState.isLocalNed){
1370 std::cout<<"Drone #"<<CopterID<<": Checking local pos successfully."<<std::endl;
1371 mavState.selfCheckState=2;
1372 SelfCheckMainState=2; //go to mode 2.
1373 }
1374 }
1375
1376 if(SelfCheckMainState==2){
1377 // send offboard vel=0
1378 SendVelNED(0,0,0,0);
1379
1380 if(SelfCheckSubState==0){
1381 lastTime=t; //Record sim time.
1382 SelfCheckSubState=1;
1383 }
1384 if(SelfCheckSubState==1){
1385 sendMavEnableGuided(true);
1386 SelfCheckSubState=2;
1387 lastTime=t; //Record sim time.
1388 }
1389 if(SelfCheckSubState==2){
1390 if(t-lastTime>1){
1391 if(mavState.isOffboard){
1392 std::cout<<"Drone #"<<CopterID<<": Checking offboard successfully."<<std::endl;
1393 mavState.selfCheckState=3;
1394 SelfCheckMainState=3; //go to mode 3.
1395 SelfCheckSubState=0;
1396 }
1397 else{
1398 SelfCheckSubState=1;
1399 }
1400 }
1401 }
1402 }
1403
1404 if(SelfCheckMainState==3){
1405 // send offboard vel=0
1406 SendVelNED(0,0,0,0);
1407
1408 if(SelfCheckSubState==0){
1409 lastTime=t; //Record sim time.
1410 // send arm cmd
1411 SendMavArm(true);
1412 SelfCheckSubState=1;
1413 }
1414
1415 if(SelfCheckSubState==1){
1416 if(t-lastTime>1){
1417 if(mavState.isArmed){
1418 std::cout<<"Drone #"<<CopterID<<": Checking arm successfully."<<std::endl;
1419 mavState.selfCheckState=4;
1420 SelfCheckMainState=4; //go to mode 4.
1421 }
1422 SelfCheckSubState = 0;
1423 }
1424 }
1425 }
1426
1427 if(SelfCheckMainState==4){
1428 SendVelNED(0,0,0,0);
1429
1430 if(SelfCheckSubState==0){
1431 lastTime=t; //Record sim time.
1432 SelfCheckSubState=1;
1433 sendMavEnableGuided(false);
1434 SendMavArm(false);
1435 }
1436
1437 if(SelfCheckSubState==1){
1438 if(t-lastTime>1){
1439 if(!mavState.isArmed && !mavState.isOffboard){
1440 std::cout<<"Drone #"<<CopterID<<": Checking passed."<<std::endl;
1441 mavState.selfCheckState=5;
1442 SelfCheckMainState=5; //go to mode 5
1443 }
1444 SelfCheckSubState=0;
1445 }
1446 }
1447 }
1448
1449 if(SelfCheckMainState==5){
1450 return true;
1451 }
1452 return false;
1453 }
1454};
定义 rfly_udp.h:359
定义 rfly_mavlink.h:75
定义 rfly_data.h:93
定义 rfly_data.h:291
定义 rfly_data.h:228
定义 rfly_data.h:266
定义 rfly_mavlink.h:59