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:
Nick Foster
2012-06-13 07:49:22 -07:00
parent c16886c4c1
commit 17f7cb9a53
13 changed files with 567 additions and 133 deletions
+1 -1
View File
@@ -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")
+7 -9
View File
@@ -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
+7 -7
View File
@@ -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);
+8 -21
View File
@@ -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;
}