UserCode.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478
  1. #include "Sub.h"
  2. #ifdef USERHOOK_INIT
  3. void Sub::userhook_init()
  4. {
  5. // put your initialisation code here
  6. // this will be called once at start-up
  7. }
  8. #endif
  9. #ifdef USERHOOK_FASTLOOP
  10. void Sub::userhook_FastLoop()
  11. {
  12. // put your 100Hz code here
  13. }
  14. #endif
  15. #ifdef USERHOOK_50HZLOOP
  16. extern mavlink_rov_control_t rov_control;
  17. void Sub::userhook_50Hz()
  18. {
  19. USBL_PowerSwitch();
  20. getgain();
  21. getyaw();
  22. }
  23. #endif
  24. #ifdef USERHOOK_MEDIUMLOOP
  25. void Sub::userhook_MediumLoop()
  26. {
  27. // put your 10Hz code here
  28. }
  29. #endif
  30. #ifdef USERHOOK_SLOWLOOP
  31. void Sub::userhook_SlowLoop()
  32. {
  33. // put your 3.3Hz code here
  34. }
  35. #endif
  36. #ifdef USERHOOK_SUPERSLOWLOOP
  37. void Sub::userhook_SuperSlowLoop()
  38. {
  39. // put your 1Hz code here
  40. }
  41. #endif
  42. void Sub::USBL_PowerSwitch(void)
  43. {
  44. if (rov_control.floodlight == 1 && motors.armed())
  45. {
  46. lights = 1;
  47. }else {
  48. lights = 0;
  49. }
  50. if(motors.armed() && rov_control.USBL_flag==1 ){
  51. usblpoweroff = 1;//usbl
  52. }else{
  53. usblpoweroff = 0;//usbl
  54. }
  55. }
  56. extern mavlink_rov_state_monitoring_t rov_message;
  57. void Sub::getgain(void){
  58. //上位机设置油门
  59. //uint16_t _gain = SRV_Channels::srv_channel(9)->get_output_min();//上位机设置油门
  60. gain = 1.0;
  61. static int j = 0;
  62. j++;
  63. if(j>800)
  64. {
  65. //gcs().send_text(MAV_SEVERITY_WARNING, " gain %f\n",(float)gain);
  66. j=0;
  67. }
  68. }
  69. void Sub::getyaw(void){
  70. if (!motors.armed()){
  71. yaw_press = (int16_t)(ahrs.yaw_sensor/100);//记住方位
  72. return;
  73. }else{
  74. }
  75. }
  76. void Sub::updat_Atom(void){
  77. uart2_read_Atom(hal.uartD);
  78. GetAngle();
  79. }
  80. void Sub::uart2_read_Atom(AP_HAL::UARTDriver *uart)
  81. {
  82. if (uart == nullptr) {
  83. return;
  84. }
  85. uint32_t readtime=AP_HAL::micros();
  86. unsigned char received_char;
  87. unsigned char Xordata;
  88. unsigned char last_byte;
  89. while(uart->available())//recive num
  90. {
  91. received_char = uart->read();
  92. ucRxBufferATOM[ucRxCnt_atom]=received_char;
  93. //数据头是41 78 -----------------------
  94. if(ucRxBufferATOM[0]!=0x41) {
  95. ucRxCnt_atom=0;
  96. // 不是头
  97. continue;
  98. } else if(ucRxCnt_atom>0 && ucRxBufferATOM[1]!=0x78){
  99. ucRxCnt_atom=0;
  100. //不是头
  101. continue;
  102. }
  103. //---------------------
  104. ucRxCnt_atom++;
  105. last_byte =ucRxBufferATOM[5]+7;//数据个数ucRxBufferATOM[5] + 帧头6个:41 78 FF 06 81 35+校验1+尾6d
  106. if(ucRxCnt_atom>last_byte && ucRxBufferATOM[last_byte]==0x6D)
  107. {
  108. break;
  109. }
  110. if(AP_HAL::micros() - readtime >800)//时间溢出0.8ms
  111. {//接收数据超时
  112. ucRxCnt_atom=0;
  113. usart_state_atom =FALSE;//通信失败
  114. memset(ucRxBufferATOM, 0, sizeof(unsigned char)*256);
  115. gcs().send_text(MAV_SEVERITY_INFO, "atom read timeout");
  116. return;
  117. }
  118. }
  119. if (ucRxCnt_atom==0 ){//没有接收到数据
  120. return;
  121. }else{
  122. //异或校验
  123. Xordata =Atom_BBC(ucRxBufferATOM,ucRxCnt_atom-2);
  124. if (Xordata != ucRxBufferATOM[ucRxCnt_atom-2])
  125. {//校验失败
  126. static int j = 0;
  127. j++;
  128. if(j>400)
  129. {
  130. gcs().send_text(MAV_SEVERITY_INFO, " ATOM 400 times error \n");
  131. j=0;
  132. }
  133. ucRxCnt_atom =0;
  134. usart_state_atom =FALSE; //通信失败
  135. memset(ucRxBufferATOM, 0, sizeof(unsigned char)*256);
  136. return;
  137. }
  138. usart_state_atom =TRUE;//通信成功
  139. ucRxCnt_atom =0;
  140. }
  141. }
  142. //原子九轴校验 异或校验
  143. unsigned char Sub::Atom_BBC(unsigned char *addr,uint16_t len)
  144. {
  145. unsigned char *DataPoint;
  146. DataPoint = addr;
  147. unsigned char XorData = 0;
  148. unsigned short DataLength=len;
  149. while(DataLength--)
  150. {
  151. XorData = XorData ^ *DataPoint;
  152. DataPoint++;
  153. }
  154. return XorData;
  155. }
  156. void Sub::GetAngle(void)
  157. {
  158. //添加数据
  159. uint16_t data_cnt_sum ;
  160. data_cnt_sum = ucRxBufferATOM[5]+6;//6个字节的帧头
  161. uint32_t data_adress[127];
  162. uint16_t data_cnt;
  163. uint16_t adress_index = 0;
  164. uint16_t data_index=6;
  165. uint16_t SaberID = 0x0000;
  166. uint16_t i =0;
  167. if (usart_state_atom == TRUE )
  168. {
  169. //收到的是命令
  170. SaberID = ucRxBufferATOM[3]+(ucRxBufferATOM[4]<<8);
  171. }
  172. if(usart_state_atom ==TRUE && (SaberID== RespAllStatusID ||SaberID == SystemResetAckID))
  173. { //接收到的是命令反馈
  174. for(i=0;i<12;i++){
  175. SaberCommandRes[i] = ucRxBufferATOM[i];
  176. }
  177. usart_state_atom = FALSE;
  178. memset(ucRxBufferATOM, 0, sizeof(unsigned char)*256);
  179. }else if(usart_state_atom ==TRUE &&SaberID == SaberDatapacketID){//接收到的是数据
  180. while(data_index< data_cnt_sum)
  181. { //通信成功 数据包
  182. data_adress[adress_index]= (ucRxBufferATOM[data_index+1]<<8)+ ucRxBufferATOM[data_index];
  183. if (data_adress[adress_index] == 0x8C01)
  184. {//读取陀螺仪角速度
  185. GyroX = char_to_float(ucRxBufferATOM[data_index+3],ucRxBufferATOM[data_index+4],ucRxBufferATOM[data_index+5],ucRxBufferATOM[data_index+6]);
  186. GyroY = char_to_float(ucRxBufferATOM[data_index+7],ucRxBufferATOM[data_index+8],ucRxBufferATOM[data_index+9],ucRxBufferATOM[data_index+10]);
  187. GyroZ = char_to_float(ucRxBufferATOM[data_index+11],ucRxBufferATOM[data_index+12],ucRxBufferATOM[data_index+13],ucRxBufferATOM[data_index+14]);
  188. //转化成弧度
  189. GyroX=GyroX*3.14/180.0;
  190. GyroY=GyroY*3.14/180.0;
  191. GyroZ=GyroZ*3.14/180.0;
  192. }
  193. else if(data_adress[adress_index] ==0xB001)
  194. {//读取角度
  195. float yawbuf=0.0;
  196. Roll = char_to_float(ucRxBufferATOM[data_index+3],ucRxBufferATOM[data_index+4],ucRxBufferATOM[data_index+5],ucRxBufferATOM[data_index+6]);
  197. Pitch = char_to_float(ucRxBufferATOM[data_index+7],ucRxBufferATOM[data_index+8],ucRxBufferATOM[data_index+9],ucRxBufferATOM[data_index+10]);
  198. yawbuf = char_to_float(ucRxBufferATOM[data_index+11],ucRxBufferATOM[data_index+12],ucRxBufferATOM[data_index+13],ucRxBufferATOM[data_index+14]);
  199. //转化成弧度
  200. Roll_Raian =Roll*3.14/180.0;
  201. Pitch_Raian =Pitch*3.14/180.0;
  202. //yaw转化成0-360
  203. if(yawbuf < 0.0)
  204. {
  205. Yaw = 360.0 + yawbuf ;
  206. }
  207. else
  208. {
  209. Yaw = yawbuf;
  210. }
  211. //------PITCH 90度安装-----------
  212. /*Yaw_Angle = (360.0-Yaw);
  213. Yaw_Raian = Yaw_Angle*3.14/180.0;
  214. attitude_control.update_ATOM_sensor(Roll_Raian,Pitch_Raian,Yaw_Raian,GyroY,GyroX,GyroZ);//// 注意原子九轴X是俯仰 Y是翻滚应当将XY反过来试一试
  215. */
  216. //-------ROLL 90安装----------------------
  217. float yawbufraian=0.0;
  218. //原子的角速度方向和飞控相反
  219. yawbufraian =(360.0-Yaw)*3.14/180.0+1.57;
  220. Yaw_Angle = (360.0-Yaw)+90.0;
  221. //限制角度在0-360之间
  222. if (Yaw_Angle>360)
  223. {
  224. Yaw_Angle = Yaw_Angle-360;
  225. }
  226. if (yawbufraian>6.28)
  227. {
  228. Yaw_Raian = yawbufraian-6.28;
  229. }
  230. else{
  231. Yaw_Raian =yawbufraian;
  232. }
  233. attitude_control.update_ATOM_sensor(Roll_Raian,Pitch_Raian,Yaw_Raian,GyroY,GyroX,-GyroZ);//// 注意原子九轴X是俯仰 Y是翻滚应当将XY反过来试一试
  234. }
  235. data_cnt = ucRxBufferATOM[data_index+2];
  236. data_index =data_index+data_cnt +3;
  237. adress_index++;
  238. }
  239. usart_state_atom = FALSE;
  240. memset(ucRxBufferATOM, 0, sizeof(unsigned char)*256);
  241. }
  242. }
  243. //将char类型转换为float类型,输入为4个字节 小端在前,输出为float类型
  244. float Sub::char_to_float(unsigned char u1,unsigned char u2,unsigned char u3,unsigned char u4)
  245. {
  246. data_floatfromchar.u[0] = u1;
  247. data_floatfromchar.u[1] = u2;
  248. data_floatfromchar.u[2] = u3;
  249. data_floatfromchar.u[3] = u4;
  250. return data_floatfromchar.f;
  251. }
  252. #define maxangle 55.0
  253. //机器人物理空间运动状态的水平竖直切换
  254. void Sub::direction0_90(void)
  255. {
  256. static int16_t cnt=0;
  257. static int16_t cnt2=0;
  258. static int16_t cnt_backzero1=0;
  259. static int16_t cnt_backzero2=0;
  260. /*
  261. 控制区间的变化 抬头或者低头大于60度进入正负竖直状态;
  262. 进入正负竖直状态之后 外置传感器的低头抬头要保证在机器人(不是任何传感器)在空间中60到150以及-60到-150之间,保持竖直状态标志为1,超出这个范围恢复水平状态
  263. 侧歪若超过45度,说明控制不了,回到水平状态 即三个姿态均为0度
  264. 水平状态下 roll不能过大 最大控制为70度,如果超过80度 说明控制不稳定回到水平状态
  265. */
  266. /*ahrs.pitch_sensor:
  267. *(90) *(>60)
  268. * *------ *
  269. *--------* *
  270. *(<-60) *(-90)
  271. */
  272. if ((ahrs.pitch_sensor >= attitude_control.change_angle*100) && (fabsf(Pitch)<maxangle))
  273. {//大于60 侧歪<45
  274. agl_sec = section90;//正竖直
  275. }
  276. else if((ahrs.pitch_sensor <= -9000-attitude_control.Offset_ver*100) && (fabsf(Pitch)<maxangle))//Offset_ver -30
  277. {//小于-60 侧歪<45
  278. agl_sec = section_90;//负竖直
  279. }
  280. else if(agl_sec == section90)
  281. {//正竖直
  282. if (fabsf(Pitch)>=maxangle ||(Roll>-120.0 && Roll<-60)){
  283. //侧歪>45 || 外置九轴大于-120 小于-60(机器人空间姿态150 - 210度)
  284. cnt_backzero1++;
  285. if(cnt_backzero1 >50){
  286. cnt_backzero1 = 0;
  287. attitude_control.roll_pitch_back_orign = 1;//复位回到水平
  288. }
  289. }else{
  290. cnt_backzero1 = 0;
  291. }
  292. if ((Roll<150.0 && Roll>30))
  293. {//外置九轴30到150, 机器人空间姿态-60 - 60度
  294. cnt++;
  295. if (cnt>=50)
  296. {
  297. cnt = 0;
  298. agl_sec = section0;//水平
  299. }
  300. }
  301. }
  302. else if(agl_sec == section_90)
  303. {
  304. if (fabsf(Pitch)>=maxangle ||(Roll>-120.0 && Roll<-60)){
  305. //侧歪>45 || 外置九轴大于-120 小于-60(机器人空间姿态150 - 210度)
  306. cnt_backzero2++;
  307. if(cnt_backzero2 >50){
  308. cnt_backzero2 = 0;
  309. attitude_control.roll_pitch_back_orign = 1;//复位水平
  310. }
  311. }else{
  312. cnt_backzero2 = 0;
  313. }
  314. if (Roll>30 && Roll< 150)//Offset_ver -30
  315. {//外置九轴30到150, 机器人空间姿态-60 - 60度
  316. cnt2++;
  317. if (cnt2>=50)
  318. {
  319. cnt2 = 0;
  320. agl_sec = section0;//水平
  321. }
  322. }
  323. }
  324. else if(fabsf(Pitch)>=maxangle){
  325. //20210624---------------
  326. if (control_mode == STABILIZE)
  327. {
  328. attitude_control.roll_pitch_back_orign = 1;//复位回到水平
  329. }
  330. agl_sec = section0;//水平
  331. }
  332. //--------------------------------------------
  333. /* 机器人 飞控 外置九轴的空间姿态对照表
  334. 机器人pitch 飞控 pitch 九轴 roll 计算
  335. 0 0 90 90-飞控
  336. 60 60 30 90-飞控
  337. 90 90 0 90-飞控
  338. 120 60 -30 飞控-90
  339. 150 30 -60 飞控-90
  340. 180 0 -90 飞控-90
  341. 270 -90 -180 飞控-90
  342. 360 0 90 90-飞控
  343. 这里目前机器人的角度限制在-90到+90 也就是90-飞控的模式下
  344. */
  345. if (attitude_control.roll_pitch_back_orign ==1){
  346. if (fabsf(ahrs.pitch_sensor)<3000 &&fabsf(ahrs.roll_sensor)<3000)
  347. {// 确保已经回到水平状态
  348. attitude_control.roll_pitch_back_orign =0;
  349. }
  350. }
  351. if (agl_sec == section0)
  352. {//水平状态
  353. /*if (attitude_control.roll_pitch_back_orign ==1){
  354. if (fabsf(ahrs.pitch_sensor)<3000 &&fabsf(ahrs.roll_sensor)<3000)
  355. {// 确保已经回到水平状态
  356. attitude_control.roll_pitch_back_orign =0;
  357. }
  358. }*/
  359. agl_act =action_Hor;
  360. }
  361. else if(agl_sec == section90)
  362. {//竖直
  363. agl_act =action_Ver_postive;
  364. //外置九轴PID的pitch给定
  365. attitude_control.deta_angle_901 =90.0-attitude_control.angle_geiding/100.0;//注意这里angle_geiding的范围是-90到90 也就是机器人本体物理角度的-90到正90度,参照上述说明
  366. }
  367. else if(agl_sec == section_90)
  368. {//负向竖直
  369. agl_act =action_Ver_negtive;
  370. //外置九轴PID的pitch给定
  371. attitude_control.deta_angle_901 =90.0-attitude_control.angle_geiding/100.0;
  372. //外置九轴的roll范围是-180到+180
  373. if(attitude_control.deta_angle_901<-180.0)
  374. {
  375. attitude_control.deta_angle_901 = attitude_control.deta_angle_901 +360.0;
  376. }
  377. }
  378. if(agl_act ==action_Hor)
  379. {//相当于外置九轴的pitch 不能超过70度,超过非常不稳定
  380. if((ahrs.roll_sensor>7000&&ahrs.roll_sensor<8000) ||(ahrs.roll_sensor<-7000 && ahrs.roll_sensor>-8000))
  381. {
  382. //回到水平状态
  383. attitude_control.roll_pitch_back_orign =1;
  384. }
  385. else if(ahrs.roll_sensor>=8000 || ahrs.roll_sensor<=-8000)
  386. {//超过80 disarm
  387. //arming.disarm();//海检测试抗流性的时候侧着安装不能启动
  388. attitude_control.roll_pitch_back_orign =1;
  389. }
  390. }
  391. if (!motors.armed())
  392. {
  393. attitude_control.roll_pitch_back_orign = 0;
  394. }
  395. attitude_control.update_Hor_Ver_Choose(agl_act);//将状态传递到姿态控制类
  396. static int j = 0;
  397. j++;
  398. if(j>500)
  399. {
  400. // gcs().send_text(MAV_SEVERITY_WARNING, " roll_pitch_back_orign %d %d\n",(int)agl_act,(int)attitude_control.roll_pitch_back_orign);
  401. j=0;
  402. }
  403. }