Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
telemetry.c
00001 // =============================================================================================== 00002 // = UAVXArm Quadrocopter Controller = 00003 // = Copyright (c) 2008 by Prof. Greg Egan = 00004 // = Original V3.15 Copyright (c) 2007 Ing. Wolfgang Mahringer = 00005 // = http://code.google.com/p/uavp-mods/ = 00006 // =============================================================================================== 00007 00008 // This is part of UAVXArm. 00009 00010 // UAVXArm is free software: you can redistribute it and/or modify it under the terms of the GNU 00011 // General Public License as published by the Free Software Foundation, either version 3 of the 00012 // License, or (at your option) any later version. 00013 00014 // UAVXArm is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without 00015 // even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00016 // See the GNU General Public License for more details. 00017 00018 // You should have received a copy of the GNU General Public License along with this program. 00019 // If not, see http://www.gnu.org/licenses/ 00020 00021 #include "UAVXArm.h" 00022 00023 void RxTelemetryPacket(uint8); 00024 void InitTelemetryPacket(void); 00025 void BuildTelemetryPacket(uint8); 00026 00027 void SendPacketHeader(void); 00028 void SendPacketTrailer(void); 00029 00030 void SendTelemetry(void); 00031 void SendCycle(void); 00032 void SendControl(void); 00033 void SendFlightPacket(void); 00034 void SendNavPacket(void); 00035 void SendControlPacket(void); 00036 void SendStatsPacket(void); 00037 void SendParamPacket(uint8, uint8); 00038 void SendParameters(uint8); 00039 void SendMinPacket(void); 00040 void SendArduStation(void); 00041 void SendPIDTuning(void); 00042 void SendCustom(void); 00043 void SensorTrace(void); 00044 00045 uint8 UAVXCurrPacketTag; 00046 uint8 RxPacketLength, RxPacketByteCount; 00047 uint8 RxCheckSum; 00048 uint8 RxPacketTag, ReceivedPacketTag; 00049 uint8 PacketRxState; 00050 boolean CheckSumError, TelemetryPacketReceived; 00051 00052 int16 RxLengthErrors, RxTypeErrors, RxCheckSumErrors; 00053 00054 uint8 UAVXPacket[256]; 00055 00056 FILE *logfile = NULL; 00057 boolean EchoToLogFile = false; 00058 uint32 LogChars; 00059 boolean LogfileIsOpen = false; 00060 00061 uint8 TxCheckSum; 00062 00063 void InitTelemetryPacket(void) { 00064 RxPacketByteCount = 0; 00065 RxCheckSum = 0; 00066 RxPacketTag = UnknownPacketTag; 00067 RxPacketLength = 2; // set as minimum 00068 PacketRxState = WaitRxSentinel; 00069 } // InitTelemetryPacket 00070 00071 void BuildTelemetryPacket(uint8 ch) { 00072 static boolean RxPacketError; 00073 00074 UAVXPacket[RxPacketByteCount++] = ch; 00075 00076 if (RxPacketByteCount == 1) { 00077 RxPacketTag = ch; 00078 PacketRxState=WaitRxBody; 00079 } else 00080 if (RxPacketByteCount == 2) { 00081 RxPacketLength = ch; // ignore 00082 PacketRxState = WaitRxBody; 00083 } else 00084 if (RxPacketByteCount >= (RxPacketLength + 3)) { 00085 RxPacketError = CheckSumError = RxCheckSum != 0; 00086 00087 if (CheckSumError) 00088 RxCheckSumErrors++; 00089 00090 if (!RxPacketError) { 00091 TelemetryPacketReceived = true; 00092 ReceivedPacketTag=RxPacketTag; 00093 } 00094 PacketRxState = WaitRxSentinel; 00095 // InitPollPacket(); 00096 } else 00097 PacketRxState = WaitRxBody; 00098 } // BuildTelemetryPacket 00099 00100 void RxTelemetryPacket(uint8 ch) { 00101 00102 RxCheckSum ^= ch; 00103 switch (PacketRxState) { 00104 case WaitRxSentinel: 00105 if (ch == SOH) { 00106 InitTelemetryPacket(); 00107 CheckSumError = false; 00108 PacketRxState = WaitRxBody; 00109 } 00110 break; 00111 case WaitRxBody: 00112 if (ch == ESC) 00113 PacketRxState = WaitRxESC; 00114 else 00115 if (ch == SOH) { // unexpected start of packet 00116 RxLengthErrors++; 00117 00118 InitTelemetryPacket(); 00119 PacketRxState = WaitRxBody; 00120 } else 00121 if (ch == EOT) { // unexpected end of packet 00122 RxLengthErrors++; 00123 PacketRxState = WaitRxSentinel; 00124 } else 00125 BuildTelemetryPacket(ch); 00126 break; 00127 case WaitRxESC: 00128 BuildTelemetryPacket(ch); 00129 break; 00130 default: 00131 PacketRxState = WaitRxSentinel; 00132 break; 00133 } 00134 } // ParseTelemetryPacket 00135 00136 00137 #define NAV_STATS_INTERLEAVE 10 00138 static int8 StatsNavAlternate = 0; 00139 00140 void CheckTelemetry(void) { 00141 00142 // check incoming - switch on associated action 00143 00144 // do routine telemetry Tx 00145 if ( mSClock() > mS[TelemetryUpdate] ) 00146 switch ( P[TelemetryType] ) { 00147 case UAVXTelemetry: 00148 mS[TelemetryUpdate] = mSClock() + UAVX_TEL_INTERVAL_MS; 00149 SendCycle(); 00150 break; 00151 case ArduStationTelemetry: 00152 mS[TelemetryUpdate] = mSClock() + UAVX_CONTROL_TEL_INTERVAL_MS; 00153 SendArduStation(); 00154 break; 00155 case UAVXControlTelemetry: 00156 mS[TelemetryUpdate] = mSClock() + UAVX_CONTROL_TEL_INTERVAL_MS; 00157 SendControlPacket(); 00158 break; 00159 case UAVXMinTelemetry: 00160 mS[TelemetryUpdate] = mSClock() + UAVX_MIN_TEL_INTERVAL_MS; 00161 SendMinPacket(); 00162 break; 00163 case CustomTelemetry: 00164 mS[TelemetryUpdate] = mSClock() + CUSTOM_TEL_INTERVAL_MS; 00165 SendPIDTuning();//SendCustom(); 00166 break; 00167 case GPSTelemetry: 00168 break; 00169 } 00170 00171 } // CheckTelemetry 00172 00173 void SendPacketHeader(void) { 00174 00175 EchoToLogFile = true; 00176 00177 TxChar(0xff); // synchronisation to "jolt" USART 00178 TxChar(SOH); 00179 TxCheckSum = 0; 00180 } // SendPacketHeader 00181 00182 void SendPacketTrailer(void) { 00183 TxESCu8(TxCheckSum); 00184 TxChar(EOT); 00185 00186 TxChar(CR); 00187 TxChar(LF); 00188 00189 EchoToLogFile = false; 00190 } // SendPacketTrailer 00191 00192 void ShowAttitude(void) { 00193 // Stick units 00194 TxESCi16(DesiredRoll); 00195 TxESCi16(DesiredPitch); 00196 TxESCi16(DesiredYaw); 00197 00198 // mRadian and mG 00199 TxESCi16(Gyro[Roll] * 1000.0); // Rate 00200 TxESCi16(Gyro[Pitch] * 1000.0); 00201 TxESCi16(Gyro[Yaw] * 1000.0); 00202 00203 TxESCi16(Angle[Roll] * 1000.0); 00204 TxESCi16(Angle[Pitch] * 1000.0); 00205 TxESCi16(Angle[Yaw] * 1000.0); 00206 00207 TxESCi16(Acc[LR] * 1000.0); 00208 TxESCi16(Acc[BF] * 1000.0); 00209 TxESCi16(Acc[UD] * 1000.0); 00210 00211 } // ShowAttitude 00212 00213 void SendFlightPacket(void) { 00214 static int8 b; 00215 00216 SendPacketHeader(); 00217 00218 TxESCu8(UAVXFlightPacketTag); 00219 TxESCu8(58 + TELEMETRY_FLAG_BYTES); 00220 for ( b = 0; b < TELEMETRY_FLAG_BYTES; b++ ) 00221 TxESCu8(F.AllFlags[b]); 00222 00223 TxESCu8(State); 00224 00225 // dV, dA, mAH 00226 TxESCi16(BatteryVolts * 10.0); // to do scaling 00227 TxESCi16(BatteryCurrent * 10.0); 00228 TxESCi16(BatteryChargeUsedAH * 1000.0); 00229 00230 TxESCi16(RCGlitches); 00231 TxESCi16(DesiredThrottle); 00232 00233 ShowAttitude(); 00234 00235 TxESCi8((int8)Correction[LR]); 00236 TxESCi8((int8)Correction[BF]); 00237 TxESCi8((int8)AccAltComp); 00238 TxESCi8((int8)AltComp); 00239 00240 for ( b = 0; b < 8; b++ ) 00241 TxESCi16((int16)PWM[b]); 00242 00243 TxESCi24(mSClock() - mS[StartTime]); 00244 00245 SendPacketTrailer(); 00246 } // SendFlightPacket 00247 00248 void SendControlPacket(void) { 00249 static int8 b; 00250 00251 SendPacketHeader(); 00252 00253 TxESCu8(UAVXControlPacketTag); 00254 TxESCu8(48); 00255 00256 TxESCi16(DesiredThrottle); 00257 00258 ShowAttitude(); 00259 00260 TxESCu8(UAVXAirframe | 0x80); 00261 00262 for ( b = 0; b < 8; b++ ) // motor/servo channels 00263 TxESCi16((int16)PWM[b]); 00264 00265 TxESCi24( time(NULL) ); 00266 00267 SendPacketTrailer(); 00268 00269 } // SendControlPacket 00270 00271 void SendNavPacket(void) { 00272 SendPacketHeader(); 00273 00274 TxESCu8(UAVXNavPacketTag); 00275 TxESCu8(59); 00276 00277 TxESCu8(NavState); 00278 TxESCu8(FailState); 00279 TxESCu8(GPSNoOfSats); 00280 TxESCu8(GPSFix); 00281 00282 TxESCu8(CurrWP); 00283 00284 TxESCi16(ROC * 10.0 ); // dm/S 00285 TxESCi24(BaroRelAltitude * 10.0); 00286 00287 TxESCi16(GPSHeading * 1000.0); 00288 TxESCi16(RangefinderAltitude * 100.0); // cm 00289 00290 TxESCi16(GPSHDilute); 00291 TxESCi16(Heading * 1000.0); 00292 TxESCi16(WayHeading * 1000.0); 00293 00294 TxESCi16(GPSVel * 10.0); 00295 TxESCi16(0); // was GPSROC; 00296 00297 TxESCi24(GPSRelAltitude * 10.0); // dm 00298 TxESCi32(GPSLatitude); // 5 decimal minute units 00299 TxESCi32(GPSLongitude); 00300 00301 TxESCi24(DesiredAltitude * 10.0 ); 00302 TxESCi32(DesiredLatitude); 00303 TxESCi32(DesiredLongitude); 00304 00305 TxESCi24(mS[NavStateTimeout] - mSClock()); // mS 00306 00307 TxESCi16(AmbientTemperature.i16); // 0.1C 00308 TxESCi32( time(NULL) ); //GPSSeconds); 00309 00310 TxESCu8(NavSensitivity); 00311 TxESCi8(NavCorr[Roll]); 00312 TxESCi8(NavCorr[Pitch]); 00313 TxESCi8(NavCorr[Yaw]); 00314 00315 SendPacketTrailer(); 00316 00317 } // SendNavPacket 00318 00319 void SendStickPacket(void) { 00320 static uint8 c; 00321 00322 SendPacketHeader(); 00323 00324 TxESCu8(UAVXStickPacketTag); 00325 TxESCu8( 1 + RC_CONTROLS * 2 ); 00326 TxESCu8(RC_CONTROLS); 00327 for ( c = 0; c < RC_CONTROLS; c++ ) 00328 TxESCi16(RC[c]); 00329 00330 SendPacketTrailer(); 00331 } // SendStickPacket 00332 00333 void SendStatsPacket(void) { 00334 00335 static uint8 i; 00336 00337 SendPacketHeader(); 00338 00339 TxESCu8(UAVXStatsPacketTag); 00340 TxESCu8(MAX_STATS * 2 + 2); 00341 00342 for ( i = 0; i < MAX_STATS ; i++) 00343 TxESCi16(Stats[i]); 00344 00345 TxESCu8(UAVXAirframe | 0x80); 00346 TxESCu8(Orientation); 00347 00348 SendPacketTrailer(); 00349 00350 } // SendStatsPacket 00351 00352 void SendMinPacket(void) { 00353 static int8 b; 00354 00355 SendPacketHeader(); 00356 00357 TxESCu8(UAVXMinPacketTag); 00358 TxESCu8(33 + TELEMETRY_FLAG_BYTES); 00359 for ( b = 0; b < TELEMETRY_FLAG_BYTES; b++ ) 00360 TxESCu8(F.AllFlags[b]); 00361 00362 TxESCu8(State); 00363 TxESCu8(NavState); 00364 TxESCu8(FailState); 00365 00366 TxESCi16(BatteryVolts * 10.0); // to do scaling 00367 TxESCi16(BatteryCurrent * 10.0); 00368 TxESCi16(BatteryChargeUsedAH * 1000.0); 00369 00370 TxESCi16(Angle[Roll] * 1000.0); 00371 TxESCi16(Angle[Pitch] * 1000.0); 00372 00373 TxESCi24(BaroRelAltitude * 10.0); 00374 TxESCi16(RangefinderAltitude * 100.0); // cm 00375 00376 TxESCi16(Heading * 1000.0); 00377 00378 TxESCi32(GPSLatitude); // 5 decimal minute units 00379 TxESCi32(GPSLongitude); 00380 00381 TxESCu8(UAVXAirframe | 0x80 ); // ARM has top bit set 00382 TxESCu8(Orientation); 00383 00384 TxESCi24(mSClock() - mS[StartTime]); 00385 00386 SendPacketTrailer(); 00387 00388 } // SendMinPacket 00389 00390 void SendParamPacket(uint8 s, uint8 p) { 00391 00392 SendPacketHeader(); 00393 00394 TxESCu8(UAVXArmParamPacketTag); 00395 TxESCu8(6); 00396 TxESCu8(s); 00397 TxESCu8(p); 00398 TxESCi32(K[p] * 1000.0 ); 00399 00400 SendPacketTrailer(); 00401 00402 } // SendParamPacket 00403 00404 void SendParameters(uint8 s) { 00405 static uint8 p; 00406 00407 for ( p = 0; p < MAX_PARAMETERS; p++ ) 00408 SendParamPacket(s, p); 00409 SendParamPacket(0, MAX_PARAMETERS); 00410 00411 } // SendParameters 00412 00413 void SendCycle(void) { 00414 00415 switch ( UAVXCurrPacketTag ) { 00416 case UAVXFlightPacketTag: 00417 SendFlightPacket(); 00418 00419 UAVXCurrPacketTag = UAVXNavPacketTag; 00420 break; 00421 00422 case UAVXNavPacketTag: 00423 if ( ++StatsNavAlternate < NAV_STATS_INTERLEAVE) 00424 SendNavPacket(); 00425 else { 00426 SendStatsPacket(); 00427 StatsNavAlternate = 0; 00428 } 00429 00430 UAVXCurrPacketTag = UAVXFlightPacketTag; 00431 break; 00432 00433 default: 00434 UAVXCurrPacketTag = UAVXFlightPacketTag; 00435 break; 00436 } 00437 00438 } // SendCycle 00439 00440 void SendArduStation(void) { 00441 00442 static int8 Count = 0; 00443 /* 00444 Definitions of the low rate telemetry (1Hz): 00445 LAT: Latitude 00446 LON: Longitude 00447 SPD: Speed over ground from GPS 00448 CRT: Climb Rate in M/S 00449 ALT: Altitude in meters 00450 ALH: The altitude is trying to hold 00451 CRS: Course over ground in degrees. 00452 BER: Bearing is the heading you want to go 00453 WPN: Waypoint number, where WP0 is home. 00454 DST: Distance from Waypoint 00455 BTV: Battery Voltage. 00456 RSP: Roll setpoint used to debug, (not displayed here). 00457 00458 Definitions of the high rate telemetry (~4Hz): 00459 ASP: Airspeed, right now is the raw data. 00460 TTH: Throttle in 100% the autopilot is applying. 00461 RLL: Roll in degrees + is right - is left 00462 PCH: Pitch in degrees 00463 SST: Switch Status, used for debugging, but is disabled in the current version. 00464 */ 00465 00466 if ( ++Count == 4 ) { 00467 TxString("!!!"); 00468 TxString("LAT:"); 00469 TxVal32(GPSLatitude / 6000, 3, 0); 00470 TxString(",LON:"); 00471 TxVal32(GPSLongitude / 6000, 3, 0); 00472 TxString(",ALT:"); 00473 TxVal32(Altitude / 10,0,0); 00474 TxString(",ALH:"); 00475 TxVal32(DesiredAltitude / 10, 0, 0); 00476 TxString(",CRT:"); 00477 TxVal32(ROC / 100, 0, 0); 00478 TxString(",CRS:"); 00479 TxVal32(Heading * RADDEG, 0, 0); // scaling to degrees? 00480 TxString(",BER:"); 00481 TxVal32(WayHeading * RADDEG, 0, 0); 00482 TxString(",SPD:"); 00483 TxVal32(GPSVel, 0, 0); 00484 TxString(",WPN:"); 00485 TxVal32(CurrWP,0,0); 00486 TxString(",DST:"); 00487 TxVal32(0, 0, 0); // distance to WP 00488 TxString(",BTV:"); 00489 TxVal32((BatteryVoltsADC * 61)/205, 1, 0); 00490 TxString(",RSP:"); 00491 TxVal32(DesiredRoll, 0, 0); 00492 00493 Count = 0; 00494 } else { 00495 TxString("+++"); 00496 TxString("ASP:"); 00497 TxVal32(GPSVel / 100, 0, 0); 00498 TxString(",RLL:"); 00499 TxVal32(Angle[Roll] / 35, 0, 0); // scale to degrees? 00500 TxString(",PCH:"); 00501 TxVal32(Angle[Pitch] / 35, 0, 0); 00502 TxString(",THH:"); 00503 TxVal32( ((int24)DesiredThrottle * 100L) / RC_MAXIMUM, 0, 0); 00504 } 00505 00506 TxString(",***\r\n"); 00507 00508 } // SendArduStation 00509 00510 void SendPIDTuning(void) { // user defined telemetry human readable OK for small amounts of data < 1mS 00511 00512 // Fixed to roll axis 00513 00514 SendPacketHeader(); 00515 00516 TxESCu8(UAVXCustomPacketTag); 00517 TxESCu8(1 + 10); 00518 TxESCu8(5); // how many 16bit elements 00519 /* 00520 TxESCi16(DesiredRoll); 00521 TxESCi16(PWM[RightC]); 00522 00523 TxESCi16(Gyro[Roll] * 1000.0); 00524 TxESCi16(Acc[Roll] * 1000.0); 00525 TxESCi16(Angle[Roll] * 1000.0 ); 00526 */ 00527 00528 TxESCi16(DesiredYaw); 00529 TxESCi16(PWM[RightC]); 00530 00531 TxESCi16(Gyro[Yaw] * 1000.0); 00532 TxESCi16(HE * 1000.0); 00533 TxESCi16(Angle[Yaw] * 1000.0 ); 00534 00535 SendPacketTrailer(); 00536 00537 } // SendPIDTuning 00538 00539 00540 void SendCustom(void) { // user defined telemetry human readable OK for small amounts of data < 1mS 00541 00542 static uint8 s; 00543 00544 // always a vector of int16; 00545 SendPacketHeader(); 00546 00547 TxESCu8(UAVXCustomPacketTag); 00548 TxESCu8(1 + 8 + MaxAttitudeScheme * 2); 00549 TxESCu8(4 + MaxAttitudeScheme ); // how many 16bit elements 00550 TxESCi16(AttitudeMethod); 00551 00552 TxESCi16(0); // spare 00553 00554 TxESCi16(Gyro[Roll] * 1000.0); 00555 TxESCi16(Acc[LR] * 1000.0); 00556 00557 for ( s = 0; s < MaxAttitudeScheme; s++ ) 00558 TxESCi16( EstAngle[Roll][s] * 1000.0 ); 00559 00560 SendPacketTrailer(); 00561 00562 } // SendCustom 00563 00564 void SensorTrace(void) { 00565 #ifdef TESTING 00566 00567 if ( DesiredThrottle > 20 ) { 00568 EchoToLogFile = false; // direct to USART 00569 00570 TxValH16(((int24)Heading * 180)/MILLIPI); 00571 TxChar(';'); 00572 00573 TxValH16(BaroRelAltitude); 00574 TxChar(';'); 00575 TxValH16(RangefinderAltitude); 00576 TxChar(';'); 00577 TxValH16(0); 00578 TxChar(';'); 00579 00580 TxValH16(DesiredThrottle); 00581 TxChar(';'); 00582 TxValH16(DesiredRoll); 00583 TxChar(';'); 00584 TxValH16(DesiredPitch); 00585 TxChar(';'); 00586 TxValH16(DesiredYaw); 00587 TxChar(';'); 00588 00589 TxValH16(Rate[Roll]); 00590 TxChar(';'); 00591 TxValH16(Rate[Pitch]); 00592 TxChar(';'); 00593 TxValH16(Rate[Yaw]); 00594 TxChar(';'); 00595 00596 TxValH16(Angle[Roll]); 00597 TxChar(';'); 00598 TxValH16(Angle[Pitch]); 00599 TxChar(';'); 00600 TxValH16(Angle[Yaw]); 00601 TxChar(';'); 00602 00603 TxValH16(Acc[LR]); 00604 TxChar(';'); 00605 TxValH16(Acc[FB]); 00606 TxChar(';'); 00607 TxValH16(Acc[DU]); 00608 TxChar(';'); 00609 00610 TxValH16(Correction[LR]); 00611 TxChar(';'); 00612 TxValH16(Correction[FB]); 00613 TxChar(';'); 00614 TxValH16(AccAltComp); 00615 TxChar(';'); 00616 TxValH16(AltComp); 00617 TxChar(';'); 00618 TxNextLine(); 00619 } 00620 #endif // TESTING 00621 } // SensorTrace
Generated on Wed Jul 13 2022 01:50:20 by
1.7.2