mirror of
https://github.com/30hours/blah2.git
synced 2024-11-18 12:33:58 +00:00
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:
parent
6cdc7e0289
commit
7007efda0e
12 changed files with 418 additions and 117 deletions
120
api/server.js
120
api/server.js
|
@ -6,6 +6,7 @@ var stash_map = require('./stash/maxhold.js');
|
|||
var stash_detection = require('./stash/detection.js');
|
||||
var stash_iqdata = require('./stash/iqdata.js');
|
||||
var stash_timing = require('./stash/timing.js');
|
||||
var stash_falsetargets = require('./stash/falsetargets.js');
|
||||
|
||||
// constants
|
||||
const PORT = 3000;
|
||||
|
@ -16,6 +17,7 @@ var track = '';
|
|||
var timestamp = '';
|
||||
var timing = '';
|
||||
var iqdata = '';
|
||||
var falsetargets = '';
|
||||
var data = '';
|
||||
var data_map;
|
||||
var data_detection;
|
||||
|
@ -23,12 +25,13 @@ var data_tracker;
|
|||
var data_timestamp;
|
||||
var data_timing;
|
||||
var data_iqdata;
|
||||
var data_falsetargets;
|
||||
var capture = false;
|
||||
|
||||
// api server
|
||||
const app = express();
|
||||
// header on all requests
|
||||
app.use(function(req, res, next) {
|
||||
app.use(function (req, res, next) {
|
||||
res.header("Access-Control-Allow-Origin", "*");
|
||||
res.header('Cache-Control', 'private, no-cache, no-store, must-revalidate');
|
||||
res.header('Expires', '-1');
|
||||
|
@ -56,6 +59,9 @@ app.get('/api/timing', (req, res) => {
|
|||
app.get('/api/iqdata', (req, res) => {
|
||||
res.send(iqdata);
|
||||
});
|
||||
app.get('/api/falsetargets', (req, res) => {
|
||||
res.send(falsetargets);
|
||||
});
|
||||
|
||||
// stash API
|
||||
app.get('/stash/map', (req, res) => {
|
||||
|
@ -70,6 +76,9 @@ app.get('/stash/iqdata', (req, res) => {
|
|||
app.get('/stash/timing', (req, res) => {
|
||||
res.send(stash_timing.get_data_timing());
|
||||
});
|
||||
app.get('/stash/falsetargets', (req, res) => {
|
||||
res.send(stash_falsetargets.get_data_falsetargets());
|
||||
});
|
||||
|
||||
// read state of capture
|
||||
app.get('/capture', (req, res) => {
|
||||
|
@ -85,100 +94,111 @@ app.listen(PORT, HOST, () => {
|
|||
});
|
||||
|
||||
// tcp listener map
|
||||
const server_map = net.createServer((socket)=>{
|
||||
socket.write("Hello From Server!")
|
||||
socket.on("data",(msg)=>{
|
||||
data_map = data_map + msg.toString();
|
||||
if (data_map.slice(-1) === "}")
|
||||
{
|
||||
map = data_map;
|
||||
data_map = '';
|
||||
}
|
||||
});
|
||||
socket.on("close",()=>{
|
||||
console.log("Connection closed.");
|
||||
})
|
||||
const server_map = net.createServer((socket) => {
|
||||
socket.write("Hello From Server!")
|
||||
socket.on("data", (msg) => {
|
||||
data_map = data_map + msg.toString();
|
||||
if (data_map.slice(-1) === "}") {
|
||||
map = data_map;
|
||||
data_map = '';
|
||||
}
|
||||
});
|
||||
socket.on("close", () => {
|
||||
console.log("Connection closed.");
|
||||
})
|
||||
});
|
||||
server_map.listen(3001);
|
||||
|
||||
// tcp listener detection
|
||||
const server_detection = net.createServer((socket)=>{
|
||||
const server_detection = net.createServer((socket) => {
|
||||
socket.write("Hello From Server!")
|
||||
socket.on("data",(msg)=>{
|
||||
data_detection = data_detection + msg.toString();
|
||||
if (data_detection.slice(-1) === "}")
|
||||
{
|
||||
detection = data_detection;
|
||||
data_detection = '';
|
||||
}
|
||||
socket.on("data", (msg) => {
|
||||
data_detection = data_detection + msg.toString();
|
||||
if (data_detection.slice(-1) === "}") {
|
||||
detection = data_detection;
|
||||
data_detection = '';
|
||||
}
|
||||
});
|
||||
socket.on("close",()=>{
|
||||
console.log("Connection closed.");
|
||||
socket.on("close", () => {
|
||||
console.log("Connection closed.");
|
||||
})
|
||||
});
|
||||
server_detection.listen(3002);
|
||||
|
||||
// tcp listener tracker
|
||||
const server_tracker = net.createServer((socket)=>{
|
||||
const server_tracker = net.createServer((socket) => {
|
||||
socket.write("Hello From Server!")
|
||||
socket.on("data",(msg)=>{
|
||||
data_tracker = data_tracker + msg.toString();
|
||||
if (data_tracker.slice(-1) === "}")
|
||||
{
|
||||
track = data_tracker;
|
||||
data_tracker = '';
|
||||
}
|
||||
socket.on("data", (msg) => {
|
||||
data_tracker = data_tracker + msg.toString();
|
||||
if (data_tracker.slice(-1) === "}") {
|
||||
track = data_tracker;
|
||||
data_tracker = '';
|
||||
}
|
||||
});
|
||||
socket.on("close",()=>{
|
||||
console.log("Connection closed.");
|
||||
socket.on("close", () => {
|
||||
console.log("Connection closed.");
|
||||
})
|
||||
});
|
||||
server_tracker.listen(3003);
|
||||
|
||||
// tcp listener timestamp
|
||||
const server_timestamp = net.createServer((socket)=>{
|
||||
const server_timestamp = net.createServer((socket) => {
|
||||
socket.write("Hello From Server!")
|
||||
socket.on("data",(msg)=>{
|
||||
socket.on("data", (msg) => {
|
||||
data_timestamp = data_timestamp + msg.toString();
|
||||
timestamp = data_timestamp;
|
||||
data_timestamp = '';
|
||||
});
|
||||
socket.on("close",()=>{
|
||||
console.log("Connection closed.");
|
||||
socket.on("close", () => {
|
||||
console.log("Connection closed.");
|
||||
})
|
||||
});
|
||||
server_timestamp.listen(4000);
|
||||
|
||||
// tcp listener timing
|
||||
const server_timing = net.createServer((socket)=>{
|
||||
const server_timing = net.createServer((socket) => {
|
||||
socket.write("Hello From Server!")
|
||||
socket.on("data",(msg)=>{
|
||||
socket.on("data", (msg) => {
|
||||
data_timing = data_timing + msg.toString();
|
||||
if (data_timing.slice(-1) === "}")
|
||||
{
|
||||
if (data_timing.slice(-1) === "}") {
|
||||
timing = data_timing;
|
||||
data_timing = '';
|
||||
}
|
||||
});
|
||||
socket.on("close",()=>{
|
||||
console.log("Connection closed.");
|
||||
socket.on("close", () => {
|
||||
console.log("Connection closed.");
|
||||
})
|
||||
});
|
||||
server_timing.listen(4001);
|
||||
|
||||
// tcp listener iqdata metadata
|
||||
const server_iqdata = net.createServer((socket)=>{
|
||||
const server_iqdata = net.createServer((socket) => {
|
||||
socket.write("Hello From Server!")
|
||||
socket.on("data",(msg)=>{
|
||||
socket.on("data", (msg) => {
|
||||
data_iqdata = data_iqdata + msg.toString();
|
||||
if (data_iqdata.slice(-1) === "}")
|
||||
{
|
||||
if (data_iqdata.slice(-1) === "}") {
|
||||
iqdata = data_iqdata;
|
||||
data_iqdata = '';
|
||||
}
|
||||
});
|
||||
socket.on("close",()=>{
|
||||
console.log("Connection closed.");
|
||||
socket.on("close", () => {
|
||||
console.log("Connection closed.");
|
||||
})
|
||||
});
|
||||
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
50
api/stash/falsetargets.js
Normal 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;
|
|
@ -2,7 +2,7 @@ capture:
|
|||
fs: 2000000
|
||||
fc: 204640000
|
||||
device:
|
||||
type: "RspDuo"
|
||||
type: "IqSimulator"
|
||||
replay:
|
||||
state: false
|
||||
loop: true
|
||||
|
@ -14,13 +14,13 @@ process:
|
|||
buffer: 1.5
|
||||
overlap: 0
|
||||
ambiguity:
|
||||
delayMin: -10
|
||||
delayMax: 400
|
||||
dopplerMin: -200
|
||||
dopplerMax: 200
|
||||
delayMin: -10 # bins
|
||||
delayMax: 400 # bins
|
||||
dopplerMin: -200 # Hz
|
||||
dopplerMax: 200 # Hz
|
||||
clutter:
|
||||
delayMin: -10
|
||||
delayMax: 400
|
||||
delayMin: -10 # bins
|
||||
delayMax: 400 # bins
|
||||
detection:
|
||||
pfa: 0.00001
|
||||
nGuard: 2
|
||||
|
@ -46,6 +46,7 @@ network:
|
|||
timestamp: 4000
|
||||
timing: 4001
|
||||
iqdata: 4002
|
||||
falsetargets: 4003
|
||||
|
||||
truth:
|
||||
asdb:
|
||||
|
@ -58,7 +59,7 @@ truth:
|
|||
port: 30001
|
||||
|
||||
save:
|
||||
iq: true
|
||||
iq: false
|
||||
map: false
|
||||
detection: false
|
||||
timing: false
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
targets:
|
||||
- id: 1
|
||||
- id: 0
|
||||
type: "static"
|
||||
location:
|
||||
range: 10000 # meters
|
||||
|
@ -8,11 +8,21 @@ targets:
|
|||
rcs: -20 # dBsm - this is a bit contrived for a static target
|
||||
state: "active"
|
||||
|
||||
- id: 2
|
||||
- id: 1
|
||||
type: "static"
|
||||
location:
|
||||
range: 30000 # meters
|
||||
velocity:
|
||||
doppler: -150 # Hertz
|
||||
rcs: -20 # dBsm
|
||||
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"
|
|
@ -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/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/falsetargets">False Target Data</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-sm-12 col-md-12">
|
||||
|
|
25
html/display/falsetargets/index.html
Normal file
25
html/display/falsetargets/index.html
Normal 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>
|
60
html/js/table_falsetargets.js
Normal file
60
html/js/table_falsetargets.js
Normal 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);
|
|
@ -92,9 +92,7 @@ std::unique_ptr<Source> Capture::factory_source(const std::string &type, c4::yml
|
|||
{
|
||||
uint32_t n_min;
|
||||
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,
|
||||
false_targets_config_file_path);
|
||||
return std::make_unique<IqSimulator>(type, fc, fs, path, &saveIq, n_min);
|
||||
}
|
||||
// Handle unknown type
|
||||
std::cerr << "Error: Source type does not exist." << std::endl;
|
||||
|
|
|
@ -4,12 +4,14 @@
|
|||
IqSimulator::IqSimulator(std::string _type, uint32_t _fc, uint32_t _fs,
|
||||
std::string _path, bool *_saveIq,
|
||||
uint32_t _n_min = 1000,
|
||||
std::string _falseTargetsConfigFilePath = "config/false_targets.yml")
|
||||
std::string _falseTargetsConfigFilePath,
|
||||
std::string _configFilePath)
|
||||
: Source(_type, _fc, _fs, _path, _saveIq)
|
||||
{
|
||||
n_min = _n_min;
|
||||
u_int64_t total_samples = 0;
|
||||
false_targets_config_file_path = _falseTargetsConfigFilePath;
|
||||
config_file_path = _configFilePath;
|
||||
}
|
||||
|
||||
void IqSimulator::start()
|
||||
|
@ -24,7 +26,7 @@ void IqSimulator::process(IqData *buffer1, IqData *buffer2)
|
|||
{
|
||||
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)
|
||||
{
|
||||
uint32_t n_start = buffer1->get_length();
|
||||
|
|
|
@ -41,6 +41,9 @@ private:
|
|||
/// @brief Path to the false targets configuration file.
|
||||
std::string false_targets_config_file_path;
|
||||
|
||||
/// @brief Path to the radar configuration file.
|
||||
std::string config_file_path;
|
||||
|
||||
public:
|
||||
/// @brief Constructor.
|
||||
/// @param type Type of source. = "IQSimulator"
|
||||
|
@ -51,7 +54,9 @@ public:
|
|||
/// @param n Number of samples.
|
||||
/// @return The object.
|
||||
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.
|
||||
/// @param buffer1 Pointer to reference buffer.
|
||||
|
|
|
@ -5,14 +5,14 @@
|
|||
std::string ryml_get_file_copy(const char *filename);
|
||||
|
||||
// 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"};
|
||||
|
||||
// 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
|
||||
std::string config = ryml_get_file_copy(configPath.c_str());
|
||||
// Read in the false targets config file
|
||||
std::string config = ryml_get_file_copy(false_tgt_config_path.c_str());
|
||||
ryml::Tree tree = ryml::parse_in_arena(ryml::to_csubstr(config));
|
||||
|
||||
// Create a FalseTarget object for each target in the config file
|
||||
|
@ -22,7 +22,7 @@ TgtGen::TgtGen(std::string configPath, uint32_t fs)
|
|||
{
|
||||
try
|
||||
{
|
||||
targets.push_back(FalseTarget(target_node, fs));
|
||||
targets.push_back(FalseTarget(target_node, fs, fc));
|
||||
}
|
||||
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> response = std::complex<double>(0, 0);
|
||||
// loop through each target
|
||||
for (auto target : targets)
|
||||
for (auto &target : targets)
|
||||
{
|
||||
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()
|
||||
{
|
||||
return type;
|
||||
document.AddMember("false_targets", json_false_targets, allocator);
|
||||
rapidjson::StringBuffer strbuf;
|
||||
rapidjson::Writer<rapidjson::StringBuffer> writer(strbuf);
|
||||
writer.SetMaxDecimalPlaces(2);
|
||||
document.Accept(writer);
|
||||
|
||||
socket->sendData(strbuf.GetString());
|
||||
}
|
||||
|
||||
sample_counter++;
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
double FalseTarget::get_range()
|
||||
|
@ -54,14 +86,11 @@ double FalseTarget::get_range()
|
|||
return range;
|
||||
}
|
||||
|
||||
double FalseTarget::get_doppler()
|
||||
void FalseTarget::set_range(double _range)
|
||||
{
|
||||
return doppler;
|
||||
}
|
||||
|
||||
double FalseTarget::get_rcs()
|
||||
{
|
||||
return rcs;
|
||||
range = _range;
|
||||
delay = range / Constants::c;
|
||||
delay_samples = delay * fs;
|
||||
}
|
||||
|
||||
double FalseTarget::get_delay()
|
||||
|
@ -69,40 +98,72 @@ double FalseTarget::get_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["type"] >> type;
|
||||
fs = _fs;
|
||||
fc = _fc;
|
||||
sample_counter = 0;
|
||||
|
||||
if (type == TgtGen::VALID_TYPE[0])
|
||||
{
|
||||
target_node["location"]["range"] >> range;
|
||||
delay = range / 3e8;
|
||||
delay = range / Constants::c;
|
||||
delay_samples = delay * fs;
|
||||
target_node["velocity"]["doppler"] >> doppler;
|
||||
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
|
||||
{
|
||||
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;
|
||||
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));
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -111,6 +172,46 @@ std::complex<double> FalseTarget::process(IqData *buffer)
|
|||
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::ifstream in(filename, std::ios::in | std::ios::binary);
|
||||
|
|
|
@ -14,17 +14,27 @@
|
|||
|
||||
#include "data/IqData.h"
|
||||
#include "utilities/Conversions.h"
|
||||
#include "data/meta/Constants.h"
|
||||
#include "process/utility/Socket.h"
|
||||
|
||||
#include <ryml/ryml.hpp>
|
||||
#include <ryml/ryml_std.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 <string>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <fstream>
|
||||
#include <complex>
|
||||
#include <math.h>
|
||||
|
||||
#include <iomanip>
|
||||
|
||||
class FalseTarget
|
||||
{
|
||||
|
@ -32,8 +42,8 @@ private:
|
|||
/// @brief fs
|
||||
uint32_t fs;
|
||||
|
||||
/// @brief Target type.
|
||||
std::string type;
|
||||
/// @brief fc
|
||||
uint32_t fc;
|
||||
|
||||
/// @brief Target delay
|
||||
double delay;
|
||||
|
@ -44,48 +54,56 @@ private:
|
|||
/// @brief Target 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
|
||||
double doppler;
|
||||
|
||||
/// @brief Target Doppler Rate
|
||||
double doppler_rate;
|
||||
|
||||
/// @brief Target RCS
|
||||
double rcs;
|
||||
|
||||
/// @brief Target ID
|
||||
u_int32_t id;
|
||||
|
||||
public:
|
||||
/// @brief Constructor for targets.
|
||||
/// @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.
|
||||
/// @param buffer Pointer to reference buffer.
|
||||
/// @param ref_buffer Pointer to reference buffer.
|
||||
/// @return Target reflection signal.
|
||||
std::complex<double> process(IqData *buffer);
|
||||
std::complex<double> process(IqData *ref_buffer);
|
||||
|
||||
/// @brief Getter for target type.
|
||||
/// @return Target type.
|
||||
std::string get_type();
|
||||
|
||||
/// @brief Getter for target range.type
|
||||
/// @return Target range.
|
||||
/// @brief Getter for range.
|
||||
/// @return Range in meters.
|
||||
double get_range();
|
||||
|
||||
/// @brief Getter for target Doppler.
|
||||
/// @return Target Doppler.
|
||||
double get_doppler();
|
||||
/// @brief Setter for range.
|
||||
/// @param range Range in meters.
|
||||
void set_range(double range);
|
||||
|
||||
/// @brief Getter for target RCS.
|
||||
/// @return Target RCS.
|
||||
double get_rcs();
|
||||
|
||||
/// @brief Getter for target delay.
|
||||
/// @return Target delay.
|
||||
/// @brief Getter for delay.
|
||||
/// @return Delay in seconds.
|
||||
double get_delay();
|
||||
|
||||
/// @brief Getter for target id.
|
||||
/// @return Target id.
|
||||
u_int32_t get_id();
|
||||
/// @brief Setter for delay.
|
||||
/// @param delay Delay in seconds.
|
||||
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
|
||||
|
@ -94,16 +112,26 @@ private:
|
|||
/// @brief Vector of false targets.
|
||||
std::vector<FalseTarget> targets;
|
||||
|
||||
/// @brief Socket to send false target data.
|
||||
Socket *socket;
|
||||
|
||||
/// @brief Sample counter
|
||||
uint64_t sample_counter;
|
||||
|
||||
public:
|
||||
/// @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.
|
||||
static const std::string VALID_STATE[1];
|
||||
|
||||
/// @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.
|
||||
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.
|
||||
/// @param ref_buffer Pointer to reference buffer.
|
||||
|
|
Loading…
Reference in a new issue