added false target that moves in radar coordinates. The movement algorithm needs work. Also added a page in controller displaying false target truth

This commit is contained in:
bennysomers 2024-02-06 14:59:12 +11:00
parent 6cdc7e0289
commit 7007efda0e
12 changed files with 418 additions and 117 deletions

View file

@ -6,6 +6,7 @@ var stash_map = require('./stash/maxhold.js');
var stash_detection = require('./stash/detection.js'); var stash_detection = require('./stash/detection.js');
var stash_iqdata = require('./stash/iqdata.js'); var stash_iqdata = require('./stash/iqdata.js');
var stash_timing = require('./stash/timing.js'); var stash_timing = require('./stash/timing.js');
var stash_falsetargets = require('./stash/falsetargets.js');
// constants // constants
const PORT = 3000; const PORT = 3000;
@ -16,6 +17,7 @@ var track = '';
var timestamp = ''; var timestamp = '';
var timing = ''; var timing = '';
var iqdata = ''; var iqdata = '';
var falsetargets = '';
var data = ''; var data = '';
var data_map; var data_map;
var data_detection; var data_detection;
@ -23,12 +25,13 @@ var data_tracker;
var data_timestamp; var data_timestamp;
var data_timing; var data_timing;
var data_iqdata; var data_iqdata;
var data_falsetargets;
var capture = false; var capture = false;
// api server // api server
const app = express(); const app = express();
// header on all requests // header on all requests
app.use(function(req, res, next) { app.use(function (req, res, next) {
res.header("Access-Control-Allow-Origin", "*"); res.header("Access-Control-Allow-Origin", "*");
res.header('Cache-Control', 'private, no-cache, no-store, must-revalidate'); res.header('Cache-Control', 'private, no-cache, no-store, must-revalidate');
res.header('Expires', '-1'); res.header('Expires', '-1');
@ -56,6 +59,9 @@ app.get('/api/timing', (req, res) => {
app.get('/api/iqdata', (req, res) => { app.get('/api/iqdata', (req, res) => {
res.send(iqdata); res.send(iqdata);
}); });
app.get('/api/falsetargets', (req, res) => {
res.send(falsetargets);
});
// stash API // stash API
app.get('/stash/map', (req, res) => { app.get('/stash/map', (req, res) => {
@ -70,6 +76,9 @@ app.get('/stash/iqdata', (req, res) => {
app.get('/stash/timing', (req, res) => { app.get('/stash/timing', (req, res) => {
res.send(stash_timing.get_data_timing()); res.send(stash_timing.get_data_timing());
}); });
app.get('/stash/falsetargets', (req, res) => {
res.send(stash_falsetargets.get_data_falsetargets());
});
// read state of capture // read state of capture
app.get('/capture', (req, res) => { app.get('/capture', (req, res) => {
@ -85,100 +94,111 @@ app.listen(PORT, HOST, () => {
}); });
// tcp listener map // tcp listener map
const server_map = net.createServer((socket)=>{ const server_map = net.createServer((socket) => {
socket.write("Hello From Server!") socket.write("Hello From Server!")
socket.on("data",(msg)=>{ socket.on("data", (msg) => {
data_map = data_map + msg.toString(); data_map = data_map + msg.toString();
if (data_map.slice(-1) === "}") if (data_map.slice(-1) === "}") {
{ map = data_map;
map = data_map; data_map = '';
data_map = ''; }
} });
}); socket.on("close", () => {
socket.on("close",()=>{ console.log("Connection closed.");
console.log("Connection closed."); })
})
}); });
server_map.listen(3001); server_map.listen(3001);
// tcp listener detection // tcp listener detection
const server_detection = net.createServer((socket)=>{ const server_detection = net.createServer((socket) => {
socket.write("Hello From Server!") socket.write("Hello From Server!")
socket.on("data",(msg)=>{ socket.on("data", (msg) => {
data_detection = data_detection + msg.toString(); data_detection = data_detection + msg.toString();
if (data_detection.slice(-1) === "}") if (data_detection.slice(-1) === "}") {
{ detection = data_detection;
detection = data_detection; data_detection = '';
data_detection = ''; }
}
}); });
socket.on("close",()=>{ socket.on("close", () => {
console.log("Connection closed."); console.log("Connection closed.");
}) })
}); });
server_detection.listen(3002); server_detection.listen(3002);
// tcp listener tracker // tcp listener tracker
const server_tracker = net.createServer((socket)=>{ const server_tracker = net.createServer((socket) => {
socket.write("Hello From Server!") socket.write("Hello From Server!")
socket.on("data",(msg)=>{ socket.on("data", (msg) => {
data_tracker = data_tracker + msg.toString(); data_tracker = data_tracker + msg.toString();
if (data_tracker.slice(-1) === "}") if (data_tracker.slice(-1) === "}") {
{ track = data_tracker;
track = data_tracker; data_tracker = '';
data_tracker = ''; }
}
}); });
socket.on("close",()=>{ socket.on("close", () => {
console.log("Connection closed."); console.log("Connection closed.");
}) })
}); });
server_tracker.listen(3003); server_tracker.listen(3003);
// tcp listener timestamp // tcp listener timestamp
const server_timestamp = net.createServer((socket)=>{ const server_timestamp = net.createServer((socket) => {
socket.write("Hello From Server!") socket.write("Hello From Server!")
socket.on("data",(msg)=>{ socket.on("data", (msg) => {
data_timestamp = data_timestamp + msg.toString(); data_timestamp = data_timestamp + msg.toString();
timestamp = data_timestamp; timestamp = data_timestamp;
data_timestamp = ''; data_timestamp = '';
}); });
socket.on("close",()=>{ socket.on("close", () => {
console.log("Connection closed."); console.log("Connection closed.");
}) })
}); });
server_timestamp.listen(4000); server_timestamp.listen(4000);
// tcp listener timing // tcp listener timing
const server_timing = net.createServer((socket)=>{ const server_timing = net.createServer((socket) => {
socket.write("Hello From Server!") socket.write("Hello From Server!")
socket.on("data",(msg)=>{ socket.on("data", (msg) => {
data_timing = data_timing + msg.toString(); data_timing = data_timing + msg.toString();
if (data_timing.slice(-1) === "}") if (data_timing.slice(-1) === "}") {
{
timing = data_timing; timing = data_timing;
data_timing = ''; data_timing = '';
} }
}); });
socket.on("close",()=>{ socket.on("close", () => {
console.log("Connection closed."); console.log("Connection closed.");
}) })
}); });
server_timing.listen(4001); server_timing.listen(4001);
// tcp listener iqdata metadata // tcp listener iqdata metadata
const server_iqdata = net.createServer((socket)=>{ const server_iqdata = net.createServer((socket) => {
socket.write("Hello From Server!") socket.write("Hello From Server!")
socket.on("data",(msg)=>{ socket.on("data", (msg) => {
data_iqdata = data_iqdata + msg.toString(); data_iqdata = data_iqdata + msg.toString();
if (data_iqdata.slice(-1) === "}") if (data_iqdata.slice(-1) === "}") {
{
iqdata = data_iqdata; iqdata = data_iqdata;
data_iqdata = ''; data_iqdata = '';
} }
}); });
socket.on("close",()=>{ socket.on("close", () => {
console.log("Connection closed."); console.log("Connection closed.");
}) })
}); });
server_iqdata.listen(4002); server_iqdata.listen(4002);
// tcp listener falsetargets
const server_falsetargets = net.createServer((socket) => {
socket.write("Hello From Server!")
socket.on("data", (msg) => {
data_falsetargets = data_falsetargets + msg.toString();
if (data_falsetargets.slice(-1) === "}") {
falsetargets = data_falsetargets;
data_falsetargets = '';
}
});
socket.on("close", () => {
console.log("Connection closed.");
})
});
server_falsetargets.listen(4003);

50
api/stash/falsetargets.js Normal file
View file

@ -0,0 +1,50 @@
const http = require('http');
var falsetargets = [];
frequency = [];
var ts = '';
var output = [];
const options_falsetargets = {
host: '127.0.0.1',
path: '/api/falsetargets',
port: 3000
};
function update_data() {
// check if timestamp is updated
http.get(options_falsetargets, function (res) {
res.setEncoding('utf8');
res.on('data', function (body) {
if (ts != body) {
ts = body;
http.get(options_falsetargets, function (res) {
let body_map = '';
res.setEncoding('utf8');
res.on('data', (chunk) => {
body_map += chunk;
});
res.on('end', () => {
try {
output = JSON.parse(body_map);
// false targets
falsetargets.push(output.falsetargets);
} catch (e) {
console.error(e.message);
}
});
});
}
});
});
};
setInterval(update_data, 100);
function get_data() {
return output;
};
module.exports.get_data_falsetargets = get_data;

View file

@ -2,7 +2,7 @@ capture:
fs: 2000000 fs: 2000000
fc: 204640000 fc: 204640000
device: device:
type: "RspDuo" type: "IqSimulator"
replay: replay:
state: false state: false
loop: true loop: true
@ -14,13 +14,13 @@ process:
buffer: 1.5 buffer: 1.5
overlap: 0 overlap: 0
ambiguity: ambiguity:
delayMin: -10 delayMin: -10 # bins
delayMax: 400 delayMax: 400 # bins
dopplerMin: -200 dopplerMin: -200 # Hz
dopplerMax: 200 dopplerMax: 200 # Hz
clutter: clutter:
delayMin: -10 delayMin: -10 # bins
delayMax: 400 delayMax: 400 # bins
detection: detection:
pfa: 0.00001 pfa: 0.00001
nGuard: 2 nGuard: 2
@ -46,6 +46,7 @@ network:
timestamp: 4000 timestamp: 4000
timing: 4001 timing: 4001
iqdata: 4002 iqdata: 4002
falsetargets: 4003
truth: truth:
asdb: asdb:
@ -58,7 +59,7 @@ truth:
port: 30001 port: 30001
save: save:
iq: true iq: false
map: false map: false
detection: false detection: false
timing: false timing: false

View file

@ -1,5 +1,5 @@
targets: targets:
- id: 1 - id: 0
type: "static" type: "static"
location: location:
range: 10000 # meters range: 10000 # meters
@ -8,7 +8,7 @@ targets:
rcs: -20 # dBsm - this is a bit contrived for a static target rcs: -20 # dBsm - this is a bit contrived for a static target
state: "active" state: "active"
- id: 2 - id: 1
type: "static" type: "static"
location: location:
range: 30000 # meters range: 30000 # meters
@ -16,3 +16,13 @@ targets:
doppler: -150 # Hertz doppler: -150 # Hertz
rcs: -20 # dBsm rcs: -20 # dBsm
state: "active" state: "active"
- id: 2
type: "moving_radar"
location:
range: 5000 # meters
velocity:
doppler: 100 # Hertz
dopplerRate: 0 # Hertz/second
rcs: -20 # dBsm - this is also contrived
state: "active"

View file

@ -38,6 +38,7 @@
<li class="py-1"><a class="text-reset text-decoration-none" href="/display/detection/delay-doppler">Detections in delay-Doppler over time</a></li> <li class="py-1"><a class="text-reset text-decoration-none" href="/display/detection/delay-doppler">Detections in delay-Doppler over time</a></li>
<li class="py-1"><a class="text-reset text-decoration-none" href="/display/spectrum">Spectrum reference</a></li> <li class="py-1"><a class="text-reset text-decoration-none" href="/display/spectrum">Spectrum reference</a></li>
<li class="py-1"><a class="text-reset text-decoration-none" href="/display/timing">Timing display</a></li> <li class="py-1"><a class="text-reset text-decoration-none" href="/display/timing">Timing display</a></li>
<li class="py-1"><a class="text-reset text-decoration-none" href="/display/falsetargets">False Target Data</a></li>
</ul> </ul>
</div> </div>
<div class="col-sm-12 col-md-12"> <div class="col-sm-12 col-md-12">

View file

@ -0,0 +1,25 @@
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta charset="UTF-8">
<title>blah2</title>
<!-- load lib js -->
<script src="../../lib/bootstrap-5.2.3.min.js"></script>
<script src="../../lib/jquery-3.6.4.min.js"></script>
<!-- load lib css -->
<link rel="stylesheet" href="../../lib/bootstrap-5.2.3.min.css">
<style>
</style>
</head>
<body style="background-color:#f78c58;">
<div style="height: 100vh; width: 95vw" class="container-fluid">
<div style="height: 100vh; width: 95vw" class="row d-flex">
<div class="justify-content-center" id="data"></div>
</div>
</body>
<script>
xTitle = "False Targets";
</script>
<script src="../../js/table_falsetargets.js"></script>
</html>

View file

@ -0,0 +1,60 @@
var host = window.location.hostname;
var isLocalHost = (host === "localhost" || host === "127.0.0.1" || host === "192.168.0.112");
// setup API
var urlFalseTargets;
if (isLocalHost) {
urlFalseTargets = '//' + host + ':3000/api/falsetargets';
} else {
urlFalseTargets = '//' + host + '/api/falsetargets';
}
//callback function
var intervalId = window.setInterval(function () {
$.getJSON(urlFalseTargets, function (data) {
if (data != null) {
var table = document.getElementById("data");
// PLEASE SOMEONE FORMAT THIS NICER! //
var output = "";
data.false_targets.forEach((target) => {
output += "id: " + target.id + "<br>";
output += "<ul> <li>" + target.type + "</li>";
if (target.type === "static") {
output += "<li> delay: " + target.delay + "</li>";
output += "<li> delay_samples: " + target.delay_samples + "</li>";
output += "<li> range: " + target.range + "</li>";
output += "<li> doppler: " + target.doppler + "</li>";
output += "<li> rcs: " + target.rcs + "</li>";
} else if (target.type === "moving_radar") {
output += "<li> delay: " + target.delay + "</li>";
output += "<li> delay_samples: " + target.delay_samples + "</li>";
output += "<li> range: " + target.range + "</li>";
output += "<li> start_range: " + target.start_range + "</li>";
output += "<li> doppler: " + target.doppler + "</li>";
output += "<li> doppler_rate: " + target.doppler_rate + "</li>";
output += "<li> rcs: " + target.rcs + "</li>";
}
output += "</ul>";
});
table.innerHTML = output;
// data.false_targets.foreach((targetjson) => {
// target = JSON.parse(targetjson);
// console.log(target);
// });
// for (var i = 0; i < data.length; i++) {
// var row = table.insertRow(i + 1);
// var cell1 = row.insertCell(0);
// var cell2 = row.insertCell(1);
// var cell3 = row.insertCell(2);
// cell1.innerHTML = data[i].x;
// cell2.innerHTML = data[i].y;
// cell3.innerHTML = data[i].z;
// }
}
});
}, 100);

View file

@ -92,9 +92,7 @@ std::unique_ptr<Source> Capture::factory_source(const std::string &type, c4::yml
{ {
uint32_t n_min; uint32_t n_min;
n_min = 2000000; n_min = 2000000;
std::string false_targets_config_file_path = "config/false_targets.yml"; return std::make_unique<IqSimulator>(type, fc, fs, path, &saveIq, n_min);
return std::make_unique<IqSimulator>(type, fc, fs, path, &saveIq, n_min,
false_targets_config_file_path);
} }
// Handle unknown type // Handle unknown type
std::cerr << "Error: Source type does not exist." << std::endl; std::cerr << "Error: Source type does not exist." << std::endl;

View file

@ -4,12 +4,14 @@
IqSimulator::IqSimulator(std::string _type, uint32_t _fc, uint32_t _fs, IqSimulator::IqSimulator(std::string _type, uint32_t _fc, uint32_t _fs,
std::string _path, bool *_saveIq, std::string _path, bool *_saveIq,
uint32_t _n_min = 1000, uint32_t _n_min = 1000,
std::string _falseTargetsConfigFilePath = "config/false_targets.yml") std::string _falseTargetsConfigFilePath,
std::string _configFilePath)
: Source(_type, _fc, _fs, _path, _saveIq) : Source(_type, _fc, _fs, _path, _saveIq)
{ {
n_min = _n_min; n_min = _n_min;
u_int64_t total_samples = 0; u_int64_t total_samples = 0;
false_targets_config_file_path = _falseTargetsConfigFilePath; false_targets_config_file_path = _falseTargetsConfigFilePath;
config_file_path = _configFilePath;
} }
void IqSimulator::start() void IqSimulator::start()
@ -24,7 +26,7 @@ void IqSimulator::process(IqData *buffer1, IqData *buffer2)
{ {
const u_int32_t samples_per_iteration = 1000; const u_int32_t samples_per_iteration = 1000;
TgtGen false_targets = TgtGen(false_targets_config_file_path, fs); TgtGen false_targets = TgtGen(false_targets_config_file_path, config_file_path, fs, fc);
while (true) while (true)
{ {
uint32_t n_start = buffer1->get_length(); uint32_t n_start = buffer1->get_length();

View file

@ -41,6 +41,9 @@ private:
/// @brief Path to the false targets configuration file. /// @brief Path to the false targets configuration file.
std::string false_targets_config_file_path; std::string false_targets_config_file_path;
/// @brief Path to the radar configuration file.
std::string config_file_path;
public: public:
/// @brief Constructor. /// @brief Constructor.
/// @param type Type of source. = "IQSimulator" /// @param type Type of source. = "IQSimulator"
@ -51,7 +54,9 @@ public:
/// @param n Number of samples. /// @param n Number of samples.
/// @return The object. /// @return The object.
IqSimulator(std::string type, uint32_t fc, uint32_t fs, std::string path, IqSimulator(std::string type, uint32_t fc, uint32_t fs, std::string path,
bool *saveIq, uint32_t n_min, std::string false_targets_config_file_path); bool *saveIq, uint32_t n_min,
std::string false_targets_config_file_path = "config/false_targets.yml",
std::string config_file_path = "config/config.yml");
/// @brief Implement capture function on IQSimulator. /// @brief Implement capture function on IQSimulator.
/// @param buffer1 Pointer to reference buffer. /// @param buffer1 Pointer to reference buffer.

View file

@ -5,14 +5,14 @@
std::string ryml_get_file_copy(const char *filename); std::string ryml_get_file_copy(const char *filename);
// constants // constants
const std::string TgtGen::VALID_TYPE[1] = {"static"}; const std::string TgtGen::VALID_TYPE[2] = {"static", "moving_radar"};
const std::string TgtGen::VALID_STATE[1] = {"active"}; const std::string TgtGen::VALID_STATE[1] = {"active"};
// constructor // constructor
TgtGen::TgtGen(std::string configPath, uint32_t fs) TgtGen::TgtGen(std::string false_tgt_config_path, std::string config_path, uint32_t fs, uint32_t fc)
{ {
// Read in the config file // Read in the false targets config file
std::string config = ryml_get_file_copy(configPath.c_str()); std::string config = ryml_get_file_copy(false_tgt_config_path.c_str());
ryml::Tree tree = ryml::parse_in_arena(ryml::to_csubstr(config)); ryml::Tree tree = ryml::parse_in_arena(ryml::to_csubstr(config));
// Create a FalseTarget object for each target in the config file // Create a FalseTarget object for each target in the config file
@ -22,7 +22,7 @@ TgtGen::TgtGen(std::string configPath, uint32_t fs)
{ {
try try
{ {
targets.push_back(FalseTarget(target_node, fs)); targets.push_back(FalseTarget(target_node, fs, fc));
} }
catch (const std::exception &e) catch (const std::exception &e)
{ {
@ -30,23 +30,55 @@ TgtGen::TgtGen(std::string configPath, uint32_t fs)
} }
} }
} }
// Create the socket using details from the config file.
config = ryml_get_file_copy(config_path.c_str());
tree = ryml::parse_in_arena(ryml::to_csubstr(config));
std::string ip;
uint16_t port;
tree["network"]["ip"] >> ip;
tree["network"]["ports"]["falsetargets"] >> port;
socket = new Socket(ip, port);
sample_counter = 0;
} }
std::complex<double> TgtGen::process(IqData *ref_buffer) std::complex<double> TgtGen::process(IqData *ref_buffer)
{ {
std::complex<double> response = std::complex<double>(0, 0); std::complex<double> response = std::complex<double>(0, 0);
// loop through each target // loop through each target
for (auto target : targets) for (auto &target : targets)
{ {
response += target.process(ref_buffer); response += target.process(ref_buffer);
} }
return response; // output false target truth
} if (sample_counter % 100000 == 0)
{
rapidjson::Document document;
document.SetObject();
rapidjson::Document::AllocatorType &allocator = document.GetAllocator();
rapidjson::Value json_false_targets(rapidjson::kArrayType);
for (auto target : targets)
{
json_false_targets.PushBack(target.to_json(allocator), allocator);
}
std::string FalseTarget::get_type() document.AddMember("false_targets", json_false_targets, allocator);
{ rapidjson::StringBuffer strbuf;
return type; rapidjson::Writer<rapidjson::StringBuffer> writer(strbuf);
writer.SetMaxDecimalPlaces(2);
document.Accept(writer);
socket->sendData(strbuf.GetString());
}
sample_counter++;
return response;
} }
double FalseTarget::get_range() double FalseTarget::get_range()
@ -54,14 +86,11 @@ double FalseTarget::get_range()
return range; return range;
} }
double FalseTarget::get_doppler() void FalseTarget::set_range(double _range)
{ {
return doppler; range = _range;
} delay = range / Constants::c;
delay_samples = delay * fs;
double FalseTarget::get_rcs()
{
return rcs;
} }
double FalseTarget::get_delay() double FalseTarget::get_delay()
@ -69,40 +98,72 @@ double FalseTarget::get_delay()
return delay; return delay;
} }
u_int32_t FalseTarget::get_id() void FalseTarget::set_delay(double _delay)
{ {
return id; delay = _delay;
range = delay * Constants::c;
delay_samples = delay * fs;
} }
FalseTarget::FalseTarget(c4::yml::NodeRef target_node, uint32_t _fs) FalseTarget::FalseTarget(c4::yml::NodeRef target_node, uint32_t _fs, uint32_t _fc)
{ {
target_node["id"] >> id; target_node["id"] >> id;
target_node["type"] >> type; target_node["type"] >> type;
fs = _fs; fs = _fs;
fc = _fc;
sample_counter = 0;
if (type == TgtGen::VALID_TYPE[0]) if (type == TgtGen::VALID_TYPE[0])
{ {
target_node["location"]["range"] >> range; target_node["location"]["range"] >> range;
delay = range / 3e8; delay = range / Constants::c;
delay_samples = delay * fs; delay_samples = delay * fs;
target_node["velocity"]["doppler"] >> doppler; target_node["velocity"]["doppler"] >> doppler;
target_node["rcs"] >> rcs; target_node["rcs"] >> rcs;
} }
else if (type == TgtGen::VALID_TYPE[1])
{
target_node["location"]["range"] >> range;
start_range = range;
delay = range / Constants::c;
delay_samples = delay * fs;
target_node["velocity"]["doppler"] >> doppler;
target_node["velocity"]["dopplerRate"] >> doppler_rate;
target_node["rcs"] >> rcs;
}
else else
{ {
throw std::invalid_argument("Invalid target type"); throw std::invalid_argument("Invalid target type");
} }
} }
std::complex<double> FalseTarget::process(IqData *buffer) std::complex<double> FalseTarget::process(IqData *ref_buffer)
{ {
uint32_t buffer_length = buffer->get_length(); uint32_t buffer_length = ref_buffer->get_length();
std::complex<double> response = 0; std::complex<double> response = 0;
try try
{ {
response = Conversions::db2lin(rcs) * buffer->get_sample(buffer_length - delay_samples); response = Conversions::db2lin(rcs) * ref_buffer->get_sample(buffer_length - delay_samples);
response *= std::exp(std::polar<double>(1, 2 * M_PI * doppler * buffer_length / fs)); response *= std::exp(std::polar<double>(1, 2 * M_PI * doppler * buffer_length / fs));
if (type == TgtGen::VALID_TYPE[1])
{
double range_rate = -1 * doppler * Constants::c / 2.0 / fc;
set_range(range + (range_rate / fs));
// very basic PD controller
// will need tuning for different fs
doppler_rate += 0.0000001 * (range - start_range) / start_range; // target tends towards start_range
// doppler_rate -= doppler / std::abs(doppler) / std::max(std::abs(doppler), 0.1) / 100; // target tends towards 0 Doppler
doppler_rate = std::clamp(doppler_rate, -5.0, 5.0); // clamp to a reasonable value
doppler += doppler_rate / fs; // update doppler
doppler = std::clamp(doppler,
std::max(-range, -250.0),
std::min(range, 250.0)); // clamp to range
}
sample_counter++;
} }
catch (const std::exception &e) catch (const std::exception &e)
{ {
@ -111,6 +172,46 @@ std::complex<double> FalseTarget::process(IqData *buffer)
return response; return response;
} }
rapidjson::Value FalseTarget::to_json(rapidjson::Document::AllocatorType &allocator)
{
rapidjson::Value target(rapidjson::kObjectType);
target.AddMember("id", id, allocator);
target.AddMember("type", rapidjson::Value(type.c_str(), allocator).Move(), allocator);
try
{
if (type == TgtGen::VALID_TYPE[0])
{
target.AddMember("range", range, allocator);
target.AddMember("delay", delay, allocator);
target.AddMember("delay_samples", delay_samples, allocator);
target.AddMember("doppler", doppler, allocator);
target.AddMember("rcs", rcs, allocator);
}
else if (type == TgtGen::VALID_TYPE[1])
{
target.AddMember("range", range, allocator);
target.AddMember("start_range", start_range, allocator);
target.AddMember("delay", delay, allocator);
target.AddMember("delay_samples", delay_samples, allocator);
target.AddMember("doppler", doppler, allocator);
target.AddMember("doppler_rate", doppler_rate, allocator);
target.AddMember("rcs", rcs, allocator);
}
else
{
throw std::invalid_argument("Invalid target type");
}
}
catch (const std::exception &e)
{
std::cerr << e.what() << '\n';
}
return target;
}
std::string ryml_get_file_copy(const char *filename) std::string ryml_get_file_copy(const char *filename)
{ {
std::ifstream in(filename, std::ios::in | std::ios::binary); std::ifstream in(filename, std::ios::in | std::ios::binary);

View file

@ -14,17 +14,27 @@
#include "data/IqData.h" #include "data/IqData.h"
#include "utilities/Conversions.h" #include "utilities/Conversions.h"
#include "data/meta/Constants.h"
#include "process/utility/Socket.h"
#include <ryml/ryml.hpp> #include <ryml/ryml.hpp>
#include <ryml/ryml_std.hpp> #include <ryml/ryml_std.hpp>
#include <c4/format.hpp> #include <c4/format.hpp>
#include "rapidjson/document.h"
#include "rapidjson/writer.h"
#include "rapidjson/stringbuffer.h"
#include "rapidjson/filewritestream.h"
#include <stdint.h> #include <stdint.h>
#include <string> #include <string>
#include <iostream> #include <iostream>
#include <vector> #include <vector>
#include <fstream> #include <fstream>
#include <complex> #include <complex>
#include <math.h>
#include <iomanip>
class FalseTarget class FalseTarget
{ {
@ -32,8 +42,8 @@ private:
/// @brief fs /// @brief fs
uint32_t fs; uint32_t fs;
/// @brief Target type. /// @brief fc
std::string type; uint32_t fc;
/// @brief Target delay /// @brief Target delay
double delay; double delay;
@ -44,48 +54,56 @@ private:
/// @brief Target range /// @brief Target range
double range; double range;
/// @brief Target starting range
double start_range;
/// @brief Sample counter
uint64_t sample_counter;
public:
/// @brief Target type.
std::string type;
/// @brief Target Doppler /// @brief Target Doppler
double doppler; double doppler;
/// @brief Target Doppler Rate
double doppler_rate;
/// @brief Target RCS /// @brief Target RCS
double rcs; double rcs;
/// @brief Target ID /// @brief Target ID
u_int32_t id; u_int32_t id;
public:
/// @brief Constructor for targets. /// @brief Constructor for targets.
/// @return The object. /// @return The object.
FalseTarget(c4::yml::NodeRef target_node, uint32_t _fs); FalseTarget(c4::yml::NodeRef target_node, uint32_t _fs, uint32_t _fc);
/// @brief Generate the signal from a false target. /// @brief Generate the signal from a false target.
/// @param buffer Pointer to reference buffer. /// @param ref_buffer Pointer to reference buffer.
/// @return Target reflection signal. /// @return Target reflection signal.
std::complex<double> process(IqData *buffer); std::complex<double> process(IqData *ref_buffer);
/// @brief Getter for target type. /// @brief Getter for range.
/// @return Target type. /// @return Range in meters.
std::string get_type();
/// @brief Getter for target range.type
/// @return Target range.
double get_range(); double get_range();
/// @brief Getter for target Doppler. /// @brief Setter for range.
/// @return Target Doppler. /// @param range Range in meters.
double get_doppler(); void set_range(double range);
/// @brief Getter for target RCS. /// @brief Getter for delay.
/// @return Target RCS. /// @return Delay in seconds.
double get_rcs();
/// @brief Getter for target delay.
/// @return Target delay.
double get_delay(); double get_delay();
/// @brief Getter for target id. /// @brief Setter for delay.
/// @return Target id. /// @param delay Delay in seconds.
u_int32_t get_id(); void set_delay(double delay);
/// @brief Outputs false target truth as JSON
/// @return JSON string.
rapidjson::Value to_json(rapidjson::Document::AllocatorType &allocator);
}; };
class TgtGen class TgtGen
@ -94,16 +112,26 @@ private:
/// @brief Vector of false targets. /// @brief Vector of false targets.
std::vector<FalseTarget> targets; std::vector<FalseTarget> targets;
/// @brief Socket to send false target data.
Socket *socket;
/// @brief Sample counter
uint64_t sample_counter;
public: public:
/// @brief The valid false target types. /// @brief The valid false target types.
static const std::string VALID_TYPE[1]; static const std::string VALID_TYPE[2];
/// @brief The valid false target states. /// @brief The valid false target states.
static const std::string VALID_STATE[1]; static const std::string VALID_STATE[1];
/// @brief Constructor. /// @brief Constructor.
/// @param false_tgt_config_path Path to false targets configuration file.
/// @param config_path Path to blah2 config file.
/// @param fs Sample rate (Hz).
/// @param fc Center frequency (Hz).
/// @return The object. /// @return The object.
TgtGen(std::string configPath, uint32_t fs); TgtGen(std::string false_tgt_config_path, std::string config_path, uint32_t fs, uint32_t fc);
/// @brief Generate the signal from all false targets. /// @brief Generate the signal from all false targets.
/// @param ref_buffer Pointer to reference buffer. /// @param ref_buffer Pointer to reference buffer.