Backport Flightgear server from private tx branch, collapse commits.
* Added Flightgear multiplayer output interface to uhd_modes.py. This allows flight with live traffic in fgfs. * Quaternion library borrowed from PyPi and modified to generate angle/axis representation and construct rotation quat from lat/lon to ECEF. * Miscellaneous enhancements and cleanup to fix timestamps, add aircraft type field (seems to be unused anyway), turnrate info
This commit is contained in:
+1
-1
@@ -25,7 +25,7 @@ include(GrPlatform) #define LIB_SUFFIX
|
||||
add_library(air_modes SHARED
|
||||
air_modes_preamble.cc
|
||||
air_modes_slicer.cc
|
||||
modes_parity.cc
|
||||
modes_crc.cc
|
||||
)
|
||||
target_link_libraries(air_modes ${Boost_LIBRARIES} ${GRUEL_LIBRARIES} ${GNURADIO_CORE_LIBRARIES})
|
||||
set_target_properties(air_modes PROPERTIES DEFINE_SYMBOL "AIR_MODES_EXPORTS")
|
||||
|
||||
@@ -84,13 +84,15 @@ static double tag_to_timestamp(gr_tag_t tstamp, uint64_t abs_sample_cnt, double
|
||||
uint64_t ts_sample, last_whole_stamp;
|
||||
double last_frac_stamp;
|
||||
|
||||
if(tstamp.key == NULL || pmt::pmt_symbol_to_string(tstamp.key) != "timestamp") return 0;
|
||||
if(tstamp.key == NULL || pmt::pmt_symbol_to_string(tstamp.key) != "rx_time") return 0;
|
||||
|
||||
last_whole_stamp = pmt::pmt_to_uint64(pmt::pmt_tuple_ref(tstamp.value, 0));
|
||||
last_frac_stamp = pmt::pmt_to_double(pmt::pmt_tuple_ref(tstamp.value, 1));
|
||||
ts_sample = tstamp.offset;
|
||||
//std::cout << "HEY WE GOT A STAMP AT " << ticks << " TICKS AT SAMPLE " << ts_sample << " ABS SAMPLE CNT IS " << abs_sample_cnt << std::endl;
|
||||
return double(abs_sample_cnt * secs_per_sample) + last_whole_stamp + last_frac_stamp;
|
||||
|
||||
double tstime = double(abs_sample_cnt * secs_per_sample) + last_whole_stamp + last_frac_stamp;
|
||||
//std::cout << "HEY WE GOT A STAMP AT " << tstime << " TICKS AT SAMPLE " << ts_sample << " ABS SAMPLE CNT IS " << abs_sample_cnt << std::endl;
|
||||
return tstime;
|
||||
}
|
||||
|
||||
int air_modes_preamble::general_work(int noutput_items,
|
||||
@@ -112,7 +114,7 @@ int air_modes_preamble::general_work(int noutput_items,
|
||||
|
||||
uint64_t abs_sample_cnt = nitems_read(0);
|
||||
std::vector<gr_tag_t> tstamp_tags;
|
||||
get_tags_in_range(tstamp_tags, 0, abs_sample_cnt, abs_sample_cnt + ninputs, pmt::pmt_string_to_symbol("timestamp"));
|
||||
get_tags_in_range(tstamp_tags, 0, abs_sample_cnt, abs_sample_cnt + ninputs, pmt::pmt_string_to_symbol("rx_time"));
|
||||
//tags.back() is the most recent timestamp, then.
|
||||
if(tstamp_tags.size() > 0) {
|
||||
d_timestamp = tstamp_tags.back();
|
||||
@@ -174,11 +176,7 @@ int air_modes_preamble::general_work(int noutput_items,
|
||||
}
|
||||
|
||||
//get the timestamp of the preamble
|
||||
double tstamp = 0;
|
||||
|
||||
if(d_timestamp.offset != 0) {
|
||||
tstamp = tag_to_timestamp(d_timestamp, abs_sample_cnt + i, d_secs_per_sample);
|
||||
}
|
||||
double tstamp = tag_to_timestamp(d_timestamp, abs_sample_cnt + i, d_secs_per_sample);
|
||||
|
||||
//now tag the preamble
|
||||
add_item_tag(0, //stream ID
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
#include <air_modes_types.h>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include <modes_parity.h>
|
||||
#include <modes_crc.h>
|
||||
#include <iostream>
|
||||
#include <gr_tags.h>
|
||||
#include <air_modes_api.h>
|
||||
@@ -172,18 +172,18 @@ int air_modes_slicer::work(int noutput_items,
|
||||
if(rx_packet.type == Short_Packet && rx_packet.message_type != 11 && rx_packet.numlowconf > 0) {continue;}
|
||||
if(rx_packet.message_type == 11 && rx_packet.numlowconf >= 10) {continue;}
|
||||
|
||||
rx_packet.parity = modes_check_parity(rx_packet.data, packet_length);
|
||||
rx_packet.crc = modes_check_crc(rx_packet.data, packet_length);
|
||||
|
||||
//parity for packets that aren't type 11 or type 17 is encoded with the transponder ID, which we don't know
|
||||
//crc for packets that aren't type 11 or type 17 is encoded with the transponder ID, which we don't know
|
||||
//therefore we toss 'em if there's syndrome
|
||||
//parity for the other short packets is usually nonzero, so they can't really be trusted that far
|
||||
if(rx_packet.parity && (rx_packet.message_type == 11 || rx_packet.message_type == 17)) {continue;}
|
||||
//crc for the other short packets is usually nonzero, so they can't really be trusted that far
|
||||
if(rx_packet.crc && (rx_packet.message_type == 11 || rx_packet.message_type == 17)) {continue;}
|
||||
|
||||
//we no longer attempt to brute force error correct via syndrome. it really only gets you 1% additional returns,
|
||||
//at the expense of a lot of CPU time and complexity
|
||||
|
||||
//we'll replicate some data by sending the message type as the first field, followed by the first 8+24=32 bits of the packet, followed by
|
||||
//56 long packet data bits if applicable (zero-padded if not), followed by parity
|
||||
//56 long packet data bits if applicable (zero-padded if not), followed by crc
|
||||
|
||||
d_payload.str("");
|
||||
d_payload << std::dec << std::setw(2) << std::setfill('0') << rx_packet.message_type << std::hex << " ";
|
||||
@@ -209,7 +209,7 @@ int air_modes_slicer::work(int noutput_items,
|
||||
}
|
||||
}
|
||||
|
||||
d_payload << " " << std::setw(6) << rx_packet.parity << " " << std::dec << rx_packet.reference_level
|
||||
d_payload << " " << std::setw(6) << rx_packet.crc << " " << std::dec << rx_packet.reference_level
|
||||
<< " " << std::setprecision(10) << std::setw(10) << rx_packet.timestamp;
|
||||
gr_message_sptr msg = gr_make_message_from_string(std::string(d_payload.str()));
|
||||
d_queue->handle(msg);
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <air_modes_types.h>
|
||||
#include <modes_parity.h>
|
||||
#include <modes_crc.h>
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
* Index is bit position with bit 0 being the first bit after preamble
|
||||
* On short frames an offset of 56 is used.
|
||||
*/
|
||||
const unsigned int modes_parity_table[112] =
|
||||
const unsigned int modes_crc_table[112] =
|
||||
{
|
||||
0x3935ea, // Start of Long Frame CRC
|
||||
0x1c9af5,
|
||||
@@ -150,29 +150,16 @@ const unsigned int modes_parity_table[112] =
|
||||
0x000002,
|
||||
0x000001,
|
||||
};
|
||||
int modes_check_parity(unsigned char data[], int length)
|
||||
|
||||
int modes_check_crc(unsigned char data[], int length)
|
||||
{
|
||||
int short_crc, long_crc, i;
|
||||
// Check both long and short
|
||||
short_crc = 0;
|
||||
long_crc = 0;
|
||||
for(i = 0; i < 56; i++)
|
||||
int crc, i;
|
||||
for(i = 0; i < length; i++)
|
||||
{
|
||||
if(data[i/8] & (1 << (7-(i%8))))
|
||||
{
|
||||
short_crc ^= modes_parity_table[i+56];
|
||||
long_crc ^= modes_parity_table[i];
|
||||
|
||||
crc ^= modes_crc_table[i+(112-length)];
|
||||
}
|
||||
}
|
||||
for( ; i < length; i++)
|
||||
{
|
||||
if(data[i/8] & (1 << (7-(i%8))))
|
||||
{
|
||||
long_crc ^= modes_parity_table[i];
|
||||
}
|
||||
}
|
||||
if(length == 112) return long_crc;
|
||||
else return short_crc;
|
||||
return crc;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user