00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include "main.h"
00033 #include "system.h"
00034 #include "sdk.h"
00035 #include "LL_HL_comm.h"
00036 #include "uart.h"
00037 #include "time.h"
00038 #include "irq.h"
00039 #include "LPC214x.h"
00040 #include "hardware.h"
00041
00042 #include <ekf/autogen_ekf_propagation.h>
00043 #include <ekf/autogen_ekf_propagation_initialize.h>
00044
00045 struct WO_SDK_STRUCT WO_SDK;
00046 struct WO_CTRL_INPUT WO_CTRL_Input;
00047 struct RO_RC_DATA RO_RC_Data;
00048 struct RO_ALL_DATA RO_ALL_Data;
00049 struct WO_DIRECT_MOTOR_CONTROL WO_Direct_Motor_Control;
00050 struct WO_DIRECT_INDIVIDUAL_MOTOR_CONTROL WO_Direct_Individual_Motor_Control;
00051
00052 #include "gpsmath.h"
00053
00054 #include <ert_main.h>
00055 #include "dekf.h"
00056
00057
00058 volatile int64_t timestamp = 0;
00059 int64_t timeOffset = 0;
00060 unsigned short time_step = 2000;
00061 int64_t time_correction = 0;
00062
00063 short cmdLLValid = 0;
00064 unsigned char cmdLLNew = 0;
00065
00066 short extPositionValid = 0;
00067
00068 unsigned int cpuLoad = 0;
00069 unsigned int sdkCycleStartTime = 0;
00070
00071 HLI_IMU imuData;
00072 HLI_RCDATA rcData;
00073 HLI_GPS gpsData;
00074 HLI_SSDK_STATUS ssdk_status;
00075 HLI_MAG mag_data;
00076
00077
00078 HLI_EXT_POSITION extPosition;
00079 HLI_STATUS statusData;
00080
00081 short motor_state = -1;
00082 short motor_state_count = 0;
00083 unsigned int sdkLoops = 0;
00084
00085 unsigned int ssdk_reset_state = 0;
00086
00087
00088 DekfContext dekf;
00089
00090
00091
00092
00093 HLI_CMD_LL cmdLL;
00094 PacketInfo *packetCmdLL;
00095
00096
00097 HLI_MOTORS motors;
00098 PacketInfo *packetMotors;
00099
00100 HLI_EXT_POSITION ext_position_update;
00101 PacketInfo *packetExtPosition;
00102
00103
00104 HLI_CMD_HL extPositionCmd;
00105 PacketInfo *packetCmdHL;
00106
00107 HLI_TIMESYNC timeSync;
00108 PacketInfo *packetTimeSync;
00109
00110 PacketInfo *packetSSDKParams;
00111
00112
00113 HLI_CMD_LL controlEnable;
00114 PacketInfo *packetControlEnable;
00115
00116
00117
00118 HLI_BAUDRATE baudrate;
00119 PacketInfo *packetBaudrate;
00120
00121
00122 HLI_SUBSCRIPTION subscription;
00123 PacketInfo *packetSubscription;
00124
00125
00126 HLI_CONFIG hli_config;
00127 PacketInfo *packetConfig;
00128
00129
00130
00131 void sdkInit(void)
00132 {
00133
00134 statusData.have_SSDK_parameters = 0;
00135 ssdk_status.have_parameters = 0;
00136 baudrate.state = 0;
00137
00138 extPositionValid = 0;
00139
00140 hli_config.mode_position_control = HLI_MODE_POSCTRL_OFF;
00141 hli_config.mode_state_estimation = HLI_MODE_STATE_ESTIMATION_OFF;
00142 hli_config.position_control_axis_enable = 0;
00143 hli_config.battery_warning_voltage = BATTERY_WARNING_VOLTAGE;
00144
00145
00146 subscription.imu = HLI_DEFAULT_PERIOD_IMU;
00147 subscription.rcdata = HLI_DEFAULT_PERIOD_RCDATA;
00148 subscription.gps = HLI_DEFAULT_PERIOD_GPS;
00149 subscription.ssdk_debug = HLI_DEFAULT_PERIOD_SSDK_DEBUG;
00150 subscription.ekf_state = HLI_DEFAULT_PERIOD_EKF_STATE;
00151
00152
00153 packetExtPosition = registerPacket(HLI_PACKET_ID_POSITION_UPDATE, &ext_position_update);
00154 packetCmdHL = registerPacket(HLI_PACKET_ID_CONTROL_HL, &extPositionCmd);
00155 packetMotors = registerPacket(HLI_PACKET_ID_MOTORS, &motors);
00156 packetCmdLL = registerPacket(HLI_PACKET_ID_CONTROL_LL, &cmdLL);
00157 packetTimeSync = registerPacket(HLI_PACKET_ID_TIMESYNC, &timeSync);
00158 packetSSDKParams = registerPacket(HLI_PACKET_ID_SSDK_PARAMETERS, &ssdk_params);
00159 packetControlEnable = registerPacket(HLI_PACKET_ID_CONTROL_ENABLE, &controlEnable);
00160 packetBaudrate = registerPacket(HLI_PACKET_ID_BAUDRATE, &baudrate);
00161 packetSubscription = registerPacket(HLI_PACKET_ID_SUBSCRIPTION, &subscription);
00162 packetConfig = registerPacket(HLI_PACKET_ID_CONFIG, &hli_config);
00163
00164 UART0_rxFlush();
00165 UART0_txFlush();
00166
00167
00168 onboard_matlab_initialize();
00169
00170
00171 DEKF_init(&dekf, &extPosition);
00172
00173 extPosition.bitfield = 0;
00174 extPosition.count = 0;
00175 extPosition.heading = 0;
00176 extPosition.x = 0;
00177 extPosition.y = 0;
00178 extPosition.z = 0;
00179 extPosition.vX = 0;
00180 extPosition.vY = 0;
00181 extPosition.vZ = 0;
00182 extPosition.qualX = 0;
00183 extPosition.qualY = 0;
00184 extPosition.qualZ = 0;
00185 extPosition.qualVx = 0;
00186 extPosition.qualVy = 0;
00187 extPosition.qualVz = 0;
00188
00189 extPositionCmd.heading = 0;
00190 extPositionCmd.bitfield = 0;
00191 extPositionCmd.x = 0;
00192 extPositionCmd.y = 0;
00193 extPositionCmd.z = 0;
00194 extPositionCmd.vZ = 2000;
00195 extPositionCmd.vY = 2000;
00196 extPositionCmd.vZ = 2000;
00197 extPositionCmd.vYaw = 45000;
00198
00199 startAutoBaud();
00200 }
00201
00218 void SDK_mainloop(void)
00219 {
00220 sdkCycleStartTime = T1TC;
00221
00222 WO_SDK.ctrl_mode = 0x02;
00223 WO_SDK.disable_motor_onoff_by_stick = 0;
00224
00225 sdkLoops++;
00226
00227 parseRxFifo();
00228
00229
00230 if (packetCmdLL->updated)
00231 {
00232 cmdLLNew = 1;
00233 packetCmdLL->updated = 0;
00234 }
00235
00236
00237 if ((sdkLoops % CMD_MAX_PERIOD) == 0)
00238 {
00239
00240 if (cmdLLNew == 1)
00241 {
00242 cmdLLNew = 0;
00243 cmdLLValid++;
00244 }
00245 else
00246 {
00247 cmdLLValid--;
00248 }
00249
00250 if (cmdLLValid < -2)
00251 cmdLLValid = -2;
00252 else if (cmdLLValid > 3)
00253 cmdLLValid = 3;
00254 }
00255
00256
00257 if (packetMotors->updated)
00258 {
00259 motor_state = motors.motors;
00260 motor_state_count = 0;
00261 packetMotors->updated = 0;
00262 }
00263
00264
00265 if (packetCmdHL->updated)
00266 {
00267 packetCmdHL->updated = 0;
00268
00269 extPositionCmd.heading = -extPositionCmd.heading + 360000;
00270 extPositionCmd.y = -extPositionCmd.y;
00271 extPositionCmd.z = -extPositionCmd.z;
00272 extPositionCmd.vY = -extPositionCmd.vY;
00273 extPositionCmd.vZ = -extPositionCmd.vZ;
00274 extPositionCmd.vYaw = -extPositionCmd.vYaw;
00275 }
00276
00277
00278 if (packetSSDKParams->updated == 1)
00279 {
00280 packetSSDKParams->updated = 0;
00281 statusData.have_SSDK_parameters = 1;
00282 ssdk_status.have_parameters = 1;
00283 }
00284
00285
00286
00287 switch(hli_config.mode_state_estimation){
00288 case HLI_MODE_STATE_ESTIMATION_HL_SSDK:
00289 extPositionValid = 1;
00290 extPosition.bitfield = 0;
00291 extPosition.count = ext_position_update.count;
00292 extPosition.heading = -ext_position_update.heading + 360000;
00293 extPosition.x = ext_position_update.x;
00294 extPosition.y = -ext_position_update.y;
00295 extPosition.z = -ext_position_update.z;
00296 extPosition.vX = ext_position_update.vX;
00297 extPosition.vY = -ext_position_update.vY;
00298 extPosition.vZ = -ext_position_update.vZ;
00299 extPosition.qualX = ext_position_update.qualX;
00300 extPosition.qualY = ext_position_update.qualY;
00301 extPosition.qualZ = ext_position_update.qualZ;
00302 extPosition.qualVx = ext_position_update.qualVx;
00303 extPosition.qualVy = ext_position_update.qualVy;
00304 extPosition.qualVz = ext_position_update.qualVz;
00305 break;
00306 case HLI_MODE_STATE_ESTIMATION_EXT:
00307 extPositionValid = 1;
00308 extPosition.bitfield = EXT_POSITION_BYPASS_FILTER;
00309 extPosition.count = ext_position_update.count;
00310 extPosition.heading = -ext_position_update.heading + 360000;
00311 extPosition.x = ext_position_update.x;
00312 extPosition.y = -ext_position_update.y;
00313 extPosition.z = -ext_position_update.z;
00314 extPosition.vX = ext_position_update.vX;
00315 extPosition.vY = -ext_position_update.vY;
00316 extPosition.vZ = -ext_position_update.vZ;
00317 extPosition.qualX = ext_position_update.qualX;
00318 extPosition.qualY = ext_position_update.qualY;
00319 extPosition.qualZ = ext_position_update.qualZ;
00320 extPosition.qualVx = ext_position_update.qualVx;
00321 extPosition.qualVy = ext_position_update.qualVy;
00322 extPosition.qualVz = ext_position_update.qualVz;
00323 break;
00324 case HLI_MODE_STATE_ESTIMATION_HL_EKF:
00325 DEKF_step(&dekf, timestamp);
00326 if(DEKF_getInitializeEvent(&dekf) == 1)
00327 ssdk_reset_state = 1;
00328
00329 extPositionValid = 1;
00330 break;
00331 default:
00332 extPositionValid = 0;
00333 }
00334
00335
00336
00337 if (ssdk_reset_state >= 1 && ssdk_reset_state < 10)
00338 {
00339 RO_RC_Data.channel[0] = 2048;
00340 RO_RC_Data.channel[1] = 2048;
00341 RO_RC_Data.channel[2] = 2048;
00342 RO_RC_Data.channel[3] = 2048;
00343 RO_RC_Data.channel[5] = 0;
00344 ssdk_reset_state++;
00345 }
00346 else
00347 {
00348 ssdk_reset_state = 0;
00349 }
00350
00351
00352
00353
00354
00355 rt_OneStep();
00356
00357
00358
00359 short motorsRunning = LL_1khz_attitude_data.status2 & 0x1;
00360
00361 if (motor_state == -1 || motor_state == 2)
00362 {
00363
00364
00365 if (extPositionValid > 0 && statusData.have_SSDK_parameters == 1 && hli_config.mode_position_control == HLI_MODE_POSCTRL_HL)
00366 {
00367 WO_CTRL_Input.ctrl = hli_config.position_control_axis_enable;
00368 WO_SDK.ctrl_enabled = 1;
00369
00370 if(WO_CTRL_Input.yaw > 1000)
00371 WO_CTRL_Input.yaw = 1000;
00372 else if(WO_CTRL_Input.yaw < -1000)
00373 WO_CTRL_Input.yaw = -1000;
00374 }
00375
00376 else if (cmdLLValid > 0 && (hli_config.mode_position_control == HLI_MODE_POSCTRL_LL || hli_config.mode_position_control == HLI_MODE_POSCTRL_OFF))
00377 {
00378 writeCommand(cmdLL.x, -cmdLL.y, -cmdLL.yaw, cmdLL.z, hli_config.position_control_axis_enable, 1);
00379 }
00380 else
00381 {
00382 writeCommand(0, 0, 0, 0, 0, 0);
00383 }
00384 }
00385
00386 else if (motor_state == 1)
00387 {
00388 if (motor_state_count < 1500)
00389 {
00390 if (!motorsRunning)
00391 writeCommand(0, 0, 2047, 0, HLI_YAW_BIT | HLI_THRUST_BIT, 1);
00392 else if (motorsRunning)
00393 {
00394 writeCommand(0, 0, 0, 0, HLI_YAW_BIT | HLI_THRUST_BIT, 1);
00395 motor_state = 2;
00396 }
00397 }
00398 else
00399 {
00400 writeCommand(0, 0, 0, 0, HLI_YAW_BIT | HLI_THRUST_BIT, 1);
00401 motor_state = -1;
00402 }
00403 motor_state_count++;
00404 }
00405 else if (motor_state == 0)
00406 {
00407 if (motor_state_count < 1500)
00408 {
00409 if (motorsRunning)
00410 writeCommand(0, 0, 2047, 0, HLI_YAW_BIT | HLI_THRUST_BIT, 1);
00411 else if (!motorsRunning)
00412 {
00413 writeCommand(0, 0, 0, 0, HLI_YAW_BIT | HLI_THRUST_BIT, 1);
00414 motor_state = -1;
00415 }
00416 }
00417 else
00418 {
00419 writeCommand(0, 0, 0, 0, HLI_YAW_BIT | HLI_THRUST_BIT, 1);
00420 motor_state = -1;
00421 }
00422 motor_state_count++;
00423 }
00424 else
00425 {
00426
00427 writeCommand(0, 0, 0, 0, 0, 0);
00428 }
00429
00430
00431 if (WO_CTRL_Input.thrust > 4095)
00432 WO_CTRL_Input.thrust = 4095;
00433
00434
00435
00436
00437
00438 if (checkTxPeriod(subscription.imu))
00439 {
00440 sendImuData();
00441 }
00442
00443 if (checkTxPeriod(subscription.rcdata))
00444 {
00445 sendRcData();
00446 }
00447
00448 if (checkTxPeriod(subscription.gps))
00449 {
00450 sendGpsData();
00451 }
00452
00453 if ((sdkLoops + 20) % 500 == 0)
00454 {
00455 sendStatus();
00456
00457 }
00458
00459 if (checkTxPeriod(subscription.ssdk_debug))
00460 {
00461 ssdk_debug.timestamp = timestamp;
00462 writePacket2Ringbuffer(HLI_PACKET_ID_SSDK_DEBUG, (unsigned char*)&ssdk_debug, sizeof(ssdk_debug));
00463 }
00464
00465 if (checkTxPeriod(subscription.ekf_state))
00466 {
00467
00468 DEKF_sendState(&dekf, timestamp);
00469 }
00470
00471 if (checkTxPeriod(subscription.mag))
00472 {
00473 sendMagData();
00474 }
00475
00476
00477
00478 UART_send_ringbuffer();
00479
00480 synchronizeTime();
00481
00482 if (packetBaudrate->updated)
00483 {
00484 packetBaudrate->updated = 0;
00485 while (!UART0_txEmpty())
00486 ;
00487 }
00488
00489
00490
00491 unsigned int dt;
00492 if (T1TC < sdkCycleStartTime)
00493 dt = (processorClockFrequency() - sdkCycleStartTime) + T1TC;
00494 else
00495 dt = T1TC - sdkCycleStartTime;
00496
00497 cpuLoad = ControllerCyclesPerSecond * ((dt * 1e2) / processorClockFrequency());
00498
00499 watchdog();
00500 }
00501
00502 inline void writeCommand(short pitch, short roll, short yaw, short thrust, short ctrl, short enable)
00503 {
00504 WO_CTRL_Input.pitch = pitch;
00505 WO_CTRL_Input.roll = roll;
00506 WO_CTRL_Input.thrust = thrust;
00507 WO_CTRL_Input.yaw = yaw;
00508 WO_CTRL_Input.ctrl = ctrl;
00509
00510 WO_SDK.ctrl_enabled = enable;
00511 }
00512
00513 inline void sendImuData(void)
00514 {
00515 imuData.timestamp = timestamp;
00516
00517
00518
00519
00520 imuData.acc_x = LL_1khz_attitude_data.acc_x;
00521 imuData.acc_y = -LL_1khz_attitude_data.acc_y;
00522 imuData.acc_z = -LL_1khz_attitude_data.acc_z;
00523 imuData.ang_vel_roll = LL_1khz_attitude_data.angvel_roll;
00524 imuData.ang_vel_pitch = -LL_1khz_attitude_data.angvel_pitch;
00525 imuData.ang_vel_yaw = -LL_1khz_attitude_data.angvel_yaw;
00526 imuData.ang_roll = LL_1khz_attitude_data.angle_roll;
00527 imuData.ang_pitch = -LL_1khz_attitude_data.angle_pitch;
00528 imuData.ang_yaw = 36000 - LL_1khz_attitude_data.angle_yaw;
00529 imuData.differential_height = LL_1khz_attitude_data.dheight;
00530 imuData.height = LL_1khz_attitude_data.height;
00531
00532 writePacket2Ringbuffer(HLI_PACKET_ID_IMU, (unsigned char*)&imuData, sizeof(imuData));
00533 }
00534
00535 inline void sendGpsData(void)
00536 {
00537
00538 gpsData.timestamp = timestamp;
00539
00540
00541 gpsData.latitude = GPS_Data.latitude;
00542 gpsData.longitude = GPS_Data.longitude;
00543 gpsData.heading = LL_1khz_attitude_data.angle_yaw;
00544 gpsData.height = GPS_Data.height;
00545 gpsData.pressure_height = LL_1khz_attitude_data.height;
00546 gpsData.speedX = GPS_Data.speed_x;
00547 gpsData.speedY = GPS_Data.speed_y;
00548 gpsData.horizontalAccuracy = GPS_Data.horizontal_accuracy;
00549 gpsData.verticalAccuracy = GPS_Data.horizontal_accuracy;
00550 gpsData.speedAccuracy = GPS_Data.speed_accuracy;
00551 gpsData.numSatellites = GPS_Data.numSV;
00552 gpsData.status = GPS_Data.status;
00553
00554 writePacket2Ringbuffer(HLI_PACKET_ID_GPS, (unsigned char*)&gpsData, sizeof(gpsData));
00555 }
00556
00557 inline void sendStatus(void)
00558 {
00559
00560 statusData.timestamp = timestamp;
00561 statusData.battery_voltage = LL_1khz_attitude_data.battery_voltage1;
00562 statusData.cpu_load = cpuLoad;
00563 statusData.flight_mode = LL_1khz_attitude_data.flightMode;
00564 statusData.flight_time = HL_Status.flight_time;
00565
00566 if (motor_state == 0 || motor_state == 1)
00567 statusData.motors = motor_state;
00568 else if (LL_1khz_attitude_data.status2 & 0x1)
00569 statusData.motors = 2;
00570 else if (!(LL_1khz_attitude_data.status2 & 0x1))
00571 statusData.motors = -1;
00572
00573
00574
00575
00576 statusData.state_estimation = hli_config.mode_state_estimation;
00577 statusData.position_control = hli_config.mode_position_control;
00578
00579 statusData.rx_packets = UART_rxPacketCount;
00580 statusData.rx_packets_good = UART_rxGoodPacketCount;
00581
00582 writePacket2Ringbuffer(HLI_PACKET_ID_STATUS, (unsigned char*)&statusData, sizeof(statusData));
00583 }
00584
00585 inline void sendRcData(void)
00586 {
00587 int i = 0;
00588
00589 rcData.timestamp = timestamp;
00590 for (i = 0; i < sizeof(rcData.channel) / sizeof(unsigned short); i++)
00591 rcData.channel[i] = RO_RC_Data.channel[i];
00592
00593 writePacket2Ringbuffer(HLI_PACKET_ID_RC, (unsigned char*)&rcData, sizeof(rcData));
00594 }
00595
00596 inline void sendMagData(void)
00597 {
00598 mag_data.timestamp = timestamp;
00599 mag_data.x = LL_1khz_attitude_data.mag_x;
00600 mag_data.y = LL_1khz_attitude_data.mag_y;
00601 mag_data.z = LL_1khz_attitude_data.mag_z;
00602
00603 writePacket2Ringbuffer(HLI_PACKET_ID_MAG, (unsigned char*)&mag_data, sizeof(mag_data));
00604 }
00605
00606 inline void synchronizeTime()
00607 {
00608
00609
00610 if (packetTimeSync->updated)
00611 {
00612 timeOffset = (900 * timeOffset + 100 * (timeSync.ts1 * 2 - timeSync.tc1 - timestamp) / 2) / 1000;
00613 statusData.timesync_offset = timeOffset;
00614
00615 if (timeOffset > 1e5 || timeOffset < -1e5)
00616 {
00617 timestamp = timeSync.ts1;
00618 timeOffset = 0;
00619 }
00620 else if (timeOffset > 2000)
00621 timeOffset = 2000;
00622 else if (timeOffset < -2000)
00623 timeOffset = -2000;
00624
00625 if (timeOffset > 0)
00626 {
00627 time_step = 2000 / timeOffset;
00628 time_correction = 2;
00629 }
00630 else if (timeOffset < 0)
00631 {
00632 time_step = -2000 / timeOffset;
00633 time_correction = -2;
00634 }
00635 else
00636 {
00637 time_step = 2000;
00638 time_correction = 0;
00639 }
00640
00641 packetTimeSync->updated = 0;
00642 }
00643
00644
00645 if (sdkLoops % time_step == 0)
00646 {
00647 timestamp += time_correction;
00648 }
00649
00650 if (sdkLoops % 2000 == 0)
00651 {
00652 timeSync.tc1 = timestamp;
00653 timeSync.ts1 = 0;
00654 writePacket2Ringbuffer(HLI_PACKET_ID_TIMESYNC, (unsigned char*)&timeSync, sizeof(timeSync));
00655 UART_send_ringbuffer();
00656 }
00657 }
00658
00659 inline void watchdog(void)
00660 {
00661
00662 static uint32_t lastTxPackets = 0;
00663
00664
00665 if ((sdkLoops % (ControllerCyclesPerSecond * HLI_COMMUNICATION_TIMEOUT)) == 0)
00666 {
00667 if (UART_rxGoodPacketCount == lastTxPackets)
00668 {
00669 startAutoBaud();
00670 }
00671 lastTxPackets = UART_rxGoodPacketCount;
00672 }
00673 }
00674
00675 inline int checkTxPeriod(uint16_t period)
00676 {
00677 if (period == 0)
00678 return 0;
00679 else
00680 return sdkLoops % period == 0;
00681 }