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_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
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
|
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
|
||||||
|
|
|
@ -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"
|
|
@ -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">
|
||||||
|
|
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;
|
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;
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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.
|
||||||
|
|
Loading…
Reference in a new issue