kopia lustrzana https://github.com/pjalocha/esp32-ogn-tracker
More useable PilotAware transmission
rodzic
c9c4f0825d
commit
0ef3ae4819
20
main/ogn.h
20
main/ogn.h
|
@ -1300,6 +1300,26 @@ class GPS_Position: public GPS_Time
|
||||||
// return 3; } // => Australia + South America: upper half of 915MHz band
|
// return 3; } // => Australia + South America: upper half of 915MHz band
|
||||||
// return 2; } // => USA/Canada: full 915MHz band
|
// return 2; } // => USA/Canada: full 915MHz band
|
||||||
|
|
||||||
|
template <class OGNx_Packet>
|
||||||
|
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 <class OGNx_Packet>
|
template <class OGNx_Packet>
|
||||||
void Encode(OGNx_Packet &Packet, int16_t dTime) const // Encode position which is extrapolated by the given fraction of a second
|
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; //
|
{ Packet.Position.FixQuality = FixQuality<3 ? FixQuality:3; //
|
||||||
|
|
24
main/ogn1.h
24
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); }
|
{ Len += sprintf(Out+Len, " %s=%s", InfoParmName(InfoType), Value); }
|
||||||
else
|
else
|
||||||
{ Len += sprintf(Out+Len, " #%d=%s", InfoType, Value); }
|
{ Len += sprintf(Out+Len, " #%d=%s", InfoType, Value); }
|
||||||
Idx+=Chars; }
|
Idx+=Chars; }
|
||||||
Out[Len]=0; return Len; }
|
Out[Len]=0; return Len; }
|
||||||
*/
|
*/
|
||||||
void Print(void) const
|
void Print(void) const
|
||||||
|
@ -879,12 +879,12 @@ class OGN1_DiffPacket
|
||||||
union
|
union
|
||||||
{ uint32_t Word;
|
{ uint32_t Word;
|
||||||
struct
|
struct
|
||||||
{ uint8_t dTime:4;
|
{ uint8_t dTime:4; // [0..15sec] time difference
|
||||||
int32_t dLat :6;
|
int32_t dLat :6; // [-32..+31]
|
||||||
int32_t dLon :6;
|
int32_t dLon :6; // [-32..+31]
|
||||||
int32_t dAlt :5;
|
int32_t dAlt :5; // [-16..+15]
|
||||||
int32_t dVel :5;
|
int32_t dVel :5; // [-16..+15]
|
||||||
int32_t dHead:6;
|
int32_t dHead:6; // [-32..+31]
|
||||||
} ;
|
} ;
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
|
@ -892,10 +892,14 @@ class OGN1_DiffPacket
|
||||||
bool Encode(const OGN1_Packet &Pos, const OGN1_Packet &RefPos)
|
bool Encode(const OGN1_Packet &Pos, const OGN1_Packet &RefPos)
|
||||||
{ int8_t dT = RefPos.Position.Time - Pos.Position.Time; if(dT<0) dT+=60;
|
{ int8_t dT = RefPos.Position.Time - Pos.Position.Time; if(dT<0) dT+=60;
|
||||||
if(dT>15) return 0;
|
if(dT>15) return 0;
|
||||||
int32_t dAlt = RefPos.Position.Altitude - RefPos.Position.Altitude;
|
int32_t dLat = (int32_t)RefPos.Position.Latitude - (int32_t)Pos.Position.Latitude;
|
||||||
int32_t dLat = RefPos.Position.Latitude - RefPos.Position.Latitude;
|
int32_t dLon = (int32_t)RefPos.Position.Longitude - (int32_t)Pos.Position.Longitude;
|
||||||
int32_t dLon = RefPos.Position.Longitude - RefPos.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; }
|
return 1; }
|
||||||
|
|
||||||
} ;
|
} ;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
41
main/paw.h
41
main/paw.h
|
@ -30,8 +30,13 @@ class PAW_Packet
|
||||||
int8_t Climb :7; // [64fpm]
|
int8_t Climb :7; // [64fpm]
|
||||||
} ;
|
} ;
|
||||||
} ;
|
} ;
|
||||||
uint8_t Seq; // sequence number to transmit longer messages
|
union
|
||||||
uint8_t Msg[3]; // 3-byte part of the longer message
|
{ 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
|
union
|
||||||
{ uint16_t SpeedWord;
|
{ uint16_t SpeedWord;
|
||||||
struct
|
struct
|
||||||
|
@ -69,19 +74,27 @@ class PAW_Packet
|
||||||
// uint32_t getAddress(void) const { return Address>>8; } // remove the sync '$'
|
// 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
|
// 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();
|
{ Clear();
|
||||||
OGN = 1;
|
Address = Packet.Header.Address; // [24-bit]
|
||||||
Address = Packet.Header.Address;
|
if(Packet.Header.NonPos) return 0; // encode only position packets
|
||||||
AddrType = Packet.Header.AddrType;
|
AcftType = Packet.Position.AcftType; // [4-bit] aircraft-type
|
||||||
Relay = Packet.Header.Relay;
|
Altitude = Packet.DecodeAltitude(); // [m]
|
||||||
if(Packet.Header.NonPos) return 0;
|
Heading = Packet.DecodeHeading()/10; // [deg]
|
||||||
AcftType = Packet.Position.AcftType;
|
|
||||||
Altitude = Packet.DecodeAltitude();
|
|
||||||
Heading = Packet.DecodeHeading()/10;
|
|
||||||
Speed = (398*(int32_t)Packet.DecodeSpeed()+1024)>>11; // [0.1m/s] => [kts]
|
Speed = (398*(int32_t)Packet.DecodeSpeed()+1024)>>11; // [0.1m/s] => [kts]
|
||||||
Latitude = 0.0001f/60*Packet.DecodeLatitude();
|
Latitude = 0.0001f/60*Packet.DecodeLatitude(); // [deg]
|
||||||
Longitude = 0.0001f/60*Packet.DecodeLongitude();
|
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; }
|
setCRC(); return 1; }
|
||||||
|
|
||||||
uint8_t Dump(char *Out)
|
uint8_t Dump(char *Out)
|
||||||
|
@ -195,6 +208,7 @@ class PAW_RxPacket // Received PilotAware packet
|
||||||
Len+=Format_Hex(JSON+Len, AcftCat[Packet.AcftType]);
|
Len+=Format_Hex(JSON+Len, AcftCat[Packet.AcftType]);
|
||||||
JSON[Len++]='\"';
|
JSON[Len++]='\"';
|
||||||
uint32_t PosTime=Time; if(nsTime<300000000) PosTime--;
|
uint32_t PosTime=Time; if(nsTime<300000000) PosTime--;
|
||||||
|
// if(OGN)
|
||||||
Len+=Format_String(JSON+Len, ",\"time\":");
|
Len+=Format_String(JSON+Len, ",\"time\":");
|
||||||
Len+=Format_UnsDec(JSON+Len, PosTime);
|
Len+=Format_UnsDec(JSON+Len, PosTime);
|
||||||
int64_t RxTime=(int64_t)Time-PosTime; RxTime*=1000; RxTime+=nsTime/1000000;
|
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+=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, ",\"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);
|
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; }
|
return Len; }
|
||||||
|
|
||||||
} ;
|
} ;
|
||||||
|
|
44
main/rf.cpp
44
main/rf.cpp
|
@ -425,21 +425,6 @@ extern "C"
|
||||||
TxChan = RF_FreqPlan.getChannel(RF_SlotTime, 1, 1); // transmit channel
|
TxChan = RF_FreqPlan.getChannel(RF_SlotTime, 1, 1); // transmit channel
|
||||||
RX_Channel = TxChan;
|
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)
|
#if defined(WITH_FANET) && defined(WITH_RFM95)
|
||||||
const FANET_Packet *FNTpkt = FNT_TxFIFO.getRead(0); // read the packet from the FANET transmitt queue
|
const FANET_Packet *FNTpkt = FNT_TxFIFO.getRead(0); // read the packet from the FANET transmitt queue
|
||||||
if(FNTpkt) // was there any ?
|
if(FNTpkt) // was there any ?
|
||||||
|
@ -501,6 +486,35 @@ extern "C"
|
||||||
TimeSlot(TxChan, 1240-TimeSync_msTime(), TxPktData1, TRX.averRSSI, 0, TxTime);
|
TimeSlot(TxChan, 1240-TimeSync_msTime(), TxPktData1, TRX.averRSSI, 0, TxTime);
|
||||||
#endif
|
#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
|
#ifdef WITH_LORAWAN
|
||||||
if(WANtx)
|
if(WANtx)
|
||||||
{ TRX.WriteMode(RF_OPMODE_STANDBY); // TRX to standby
|
{ TRX.WriteMode(RF_OPMODE_STANDBY); // TRX to standby
|
||||||
|
|
Ładowanie…
Reference in New Issue