From 0ef3ae4819f24e6807dec1832f7f5eed447a9b19 Mon Sep 17 00:00:00 2001 From: Pawel Jalocha Date: Thu, 17 Dec 2020 01:15:13 +0000 Subject: [PATCH] More useable PilotAware transmission --- main/ogn.h | 20 ++++++++++++++++++++ main/ogn1.h | 24 ++++++++++++++---------- main/paw.h | 41 ++++++++++++++++++++++++++++------------- main/rf.cpp | 44 +++++++++++++++++++++++++++++--------------- 4 files changed, 91 insertions(+), 38 deletions(-) diff --git a/main/ogn.h b/main/ogn.h index 007f4c1..329fde3 100644 --- a/main/ogn.h +++ b/main/ogn.h @@ -1300,6 +1300,26 @@ class GPS_Position: public GPS_Time // return 3; } // => Australia + South America: upper half of 915MHz band // return 2; } // => USA/Canada: full 915MHz band + template + void Decode(const OGNx_Packet &Packet) + { FixQuality = Packet.Position.FixQuality; + FixMode = Packet.Position.FixMode+2; + PDOP = 10+Packet.DecodeDOP(); + HDOP = PDOP; VDOP = PDOP+PDOP/2; + FracSec=0; Sec=Packet.Position.Time; + Speed = Packet.DecodeSpeed(); + ClimbRate = Packet.DecodeClimbRate(); + TurnRate = Packet.DecodeTurnRate(); + Heading = Packet.DecodeHeading(); // Heading = track-over-ground + Latitude = Packet.DecodeLatitude(); + Longitude = Packet.DecodeLongitude(); + Altitude = Packet.DecodeAltitude()*10; + hasBaro=0; + if(Packet.hasBaro()) + { StdAltitude = Altitude + 10*Packet.getBaroAltDiff(); + hasBaro=1; } + } + template void Encode(OGNx_Packet &Packet, int16_t dTime) const // Encode position which is extrapolated by the given fraction of a second { Packet.Position.FixQuality = FixQuality<3 ? FixQuality:3; // diff --git a/main/ogn1.h b/main/ogn1.h index 487aced..0ea2109 100644 --- a/main/ogn1.h +++ b/main/ogn1.h @@ -230,7 +230,7 @@ class OGN1_Packet // Packet structure for the OGN tracker { Len += sprintf(Out+Len, " %s=%s", InfoParmName(InfoType), Value); } else { Len += sprintf(Out+Len, " #%d=%s", InfoType, Value); } - Idx+=Chars; } + Idx+=Chars; } Out[Len]=0; return Len; } */ void Print(void) const @@ -879,12 +879,12 @@ class OGN1_DiffPacket union { uint32_t Word; struct - { uint8_t dTime:4; - int32_t dLat :6; - int32_t dLon :6; - int32_t dAlt :5; - int32_t dVel :5; - int32_t dHead:6; + { uint8_t dTime:4; // [0..15sec] time difference + int32_t dLat :6; // [-32..+31] + int32_t dLon :6; // [-32..+31] + int32_t dAlt :5; // [-16..+15] + int32_t dVel :5; // [-16..+15] + int32_t dHead:6; // [-32..+31] } ; } ; @@ -892,10 +892,14 @@ class OGN1_DiffPacket bool Encode(const OGN1_Packet &Pos, const OGN1_Packet &RefPos) { int8_t dT = RefPos.Position.Time - Pos.Position.Time; if(dT<0) dT+=60; if(dT>15) return 0; - int32_t dAlt = RefPos.Position.Altitude - RefPos.Position.Altitude; - int32_t dLat = RefPos.Position.Latitude - RefPos.Position.Latitude; - int32_t dLon = RefPos.Position.Longitude - RefPos.Position.Longitude; + int32_t dLat = (int32_t)RefPos.Position.Latitude - (int32_t)Pos.Position.Latitude; + int32_t dLon = (int32_t)RefPos.Position.Longitude - (int32_t)Pos.Position.Longitude; + int16_t dAlt = (int16_t)RefPos.Position.Altitude - (int16_t)Pos.Position.Altitude; + int16_t dVel = (int16_t)RefPos.Position.Speed - (int16_t)Pos.Position.Speed; // [0.1m/s] difference in speed + int16_t dHead = (int16_t)RefPos.Position.Heading - (int16_t)Pos.Position.Heading; // [10bit cordic] difference in heading + dHead&=0x03FF; if(dHead&0x0200) dHead|=0xFC00; return 1; } + } ; */ diff --git a/main/paw.h b/main/paw.h index c067d99..e7d1d66 100644 --- a/main/paw.h +++ b/main/paw.h @@ -30,8 +30,13 @@ class PAW_Packet int8_t Climb :7; // [64fpm] } ; } ; - uint8_t Seq; // sequence number to transmit longer messages - uint8_t Msg[3]; // 3-byte part of the longer message + union + { uint32_t SeqMsg; + struct + { uint8_t Seq; // sequence number to transmit longer messages + uint8_t Msg[3]; // 3-byte part of the longer message + } ; + } ; union { uint16_t SpeedWord; struct @@ -69,19 +74,27 @@ class PAW_Packet // uint32_t getAddress(void) const { return Address>>8; } // remove the sync '$' // void setAddress(uint32_t Addr) { Address = (Addr<<8) | 0x24; } // set new address and set the '$' sync char - int Copy(const OGN1_Packet &Packet) + int Copy(const OGN1_Packet &Packet, bool Ext=1) { Clear(); - OGN = 1; - Address = Packet.Header.Address; - AddrType = Packet.Header.AddrType; - Relay = Packet.Header.Relay; - if(Packet.Header.NonPos) return 0; - AcftType = Packet.Position.AcftType; - Altitude = Packet.DecodeAltitude(); - Heading = Packet.DecodeHeading()/10; + Address = Packet.Header.Address; // [24-bit] + if(Packet.Header.NonPos) return 0; // encode only position packets + AcftType = Packet.Position.AcftType; // [4-bit] aircraft-type + Altitude = Packet.DecodeAltitude(); // [m] + Heading = Packet.DecodeHeading()/10; // [deg] Speed = (398*(int32_t)Packet.DecodeSpeed()+1024)>>11; // [0.1m/s] => [kts] - Latitude = 0.0001f/60*Packet.DecodeLatitude(); - Longitude = 0.0001f/60*Packet.DecodeLongitude(); + Latitude = 0.0001f/60*Packet.DecodeLatitude(); // [deg] + Longitude = 0.0001f/60*Packet.DecodeLongitude(); // [deg] + if(Ext) + { OGN=1; // extended data flag + AddrType = Packet.Header.AddrType; // [2-bit] + Relay = Packet.Header.Relay; // relay flag + Time = Packet.Position.Time; // [sec] + int32_t ClimbRate = Packet.DecodeClimbRate(); // [0.1m/s] + ClimbRate = (ClimbRate*315+512)>>10; // [64fpm] + if(ClimbRate>127) ClimbRate=127; + else if(ClimbRate<(-127)) ClimbRate=(-127); + Climb = ClimbRate; } + SeqMsg = 0; setCRC(); return 1; } uint8_t Dump(char *Out) @@ -195,6 +208,7 @@ class PAW_RxPacket // Received PilotAware packet Len+=Format_Hex(JSON+Len, AcftCat[Packet.AcftType]); JSON[Len++]='\"'; uint32_t PosTime=Time; if(nsTime<300000000) PosTime--; + // if(OGN) Len+=Format_String(JSON+Len, ",\"time\":"); Len+=Format_UnsDec(JSON+Len, PosTime); int64_t RxTime=(int64_t)Time-PosTime; RxTime*=1000; RxTime+=nsTime/1000000; @@ -202,6 +216,7 @@ class PAW_RxPacket // Received PilotAware packet Len+=Format_SignDec(JSON+Len, RxTime, 4, 3, 1); Len+=sprintf(JSON+Len, ",\"lat_deg\":%8.7f,\"lon_deg\":%8.7f,\"alt_msl_m\":%d", Packet.Latitude, Packet.Longitude, Packet.Altitude); Len+=sprintf(JSON+Len, ",\"track_deg\":%d,\"speed_mps\":%3.1f", Packet.Heading, 0.514*Packet.Speed); + if(Packet.OGN) Len+=sprintf(JSON+Len, ",\"climb_mps\":%3.1f", 0.32512*Packet.Climb); return Len; } } ; diff --git a/main/rf.cpp b/main/rf.cpp index 9b91337..ff603f2 100644 --- a/main/rf.cpp +++ b/main/rf.cpp @@ -425,21 +425,6 @@ extern "C" TxChan = RF_FreqPlan.getChannel(RF_SlotTime, 1, 1); // transmit channel RX_Channel = TxChan; -#ifdef WITH_PAW - { PAW_Packet Packet; Packet.Clear(); - Packet.Address = Parameters.Address; - Packet.AcftType = Parameters.AcftType; - Packet.setCRC(); - TRX.WriteMode(RF_OPMODE_STANDBY); - TRX.PAW_Configure(PAW_SYNC); - TRX.WriteTxPower(Parameters.TxPower); - TRX.WritePacketPAW(Packet.Byte, 24); - TRX.WriteMode(RF_OPMODE_TRANSMITTER); - vTaskDelay(10); - TRX.WriteMode(RF_OPMODE_STANDBY); - TRX.OGN_Configure(0, OGN_SYNC); } -#endif - #if defined(WITH_FANET) && defined(WITH_RFM95) const FANET_Packet *FNTpkt = FNT_TxFIFO.getRead(0); // read the packet from the FANET transmitt queue if(FNTpkt) // was there any ? @@ -501,6 +486,35 @@ extern "C" TimeSlot(TxChan, 1240-TimeSync_msTime(), TxPktData1, TRX.averRSSI, 0, TxTime); #endif +#ifdef WITH_PAW +#ifdef WITH_LORAWAN + if(!WANtx && TxPkt0) +#else + if(TxPkt0) +#endif + { PAW_Packet Packet; Packet.Clear(); + OGN1_Packet TxPkt = TxPkt0->Packet; + TxPkt.Dewhiten(); + XorShift32(RX_Random); + if(!TxPkt.Header.Relay && (RX_Random&0xC0)==0x00 && Packet.Copy(TxPkt)) + { TRX.WriteMode(RF_OPMODE_STANDBY); + TRX.PAW_Configure(PAW_SYNC); + TRX.WriteTxPower(Parameters.TxPower+6); + vTaskDelay(RX_Random&0x3F); + TRX.ClearIrqFlags(); + TRX.WritePacketPAW(Packet.Byte, 24); + TRX.WriteMode(RF_OPMODE_TRANSMITTER); + vTaskDelay(8); // wait 5ms + uint8_t Break=0; + for(uint16_t Wait=400; Wait; Wait--) // wait for transmission to end + { uint16_t Flags=TRX.ReadIrqFlags(); + if(Flags&RF_IRQ_PacketSent) Break++; + if(Break>=2) break; } + TRX.WriteMode(RF_OPMODE_STANDBY); + TRX.OGN_Configure(0, OGN_SYNC); } + } +#endif + #ifdef WITH_LORAWAN if(WANtx) { TRX.WriteMode(RF_OPMODE_STANDBY); // TRX to standby