Skip to content
Snippets Groups Projects
Commit 845bb0b4 authored by Iiro Rastas's avatar Iiro Rastas
Browse files

Add multi-group support to reconstruction

Reconstruction now supports multiple groups until rendering. This means
that the scene_A and scene_B variables are now vectors. To support this
change, a bug was fixed in configuration.cpp. Previously, instead of
adding multiple paths, the configure() method simply added the same path
multiple times. Now all paths are correctly added to the configuration.
parent 47f18841
No related branches found
No related tags found
1 merge request!186Implements #258 and implements #259 multi group
Pipeline #16868 passed
...@@ -136,7 +136,16 @@ static void run(ftl::Configurable *root) { ...@@ -136,7 +136,16 @@ static void run(ftl::Configurable *root) {
net->start(); net->start();
net->waitConnections(); net->waitConnections();
// Check paths for an FTL file to load... std::vector<int> sourcecounts;
// Add sources from the configuration file as a single group.
auto configuration_sources = root->getConfig()["sources"];
size_t configuration_size = configuration_sources.size();
if (configuration_size > 0) {
sourcecounts.push_back(configuration_size);
}
// Check paths for FTL files to load.
auto paths = (*root->get<nlohmann::json>("paths")); auto paths = (*root->get<nlohmann::json>("paths"));
for (auto &x : paths.items()) { for (auto &x : paths.items()) {
std::string path = x.value().get<std::string>(); std::string path = x.value().get<std::string>();
...@@ -162,9 +171,11 @@ static void run(ftl::Configurable *root) { ...@@ -162,9 +171,11 @@ static void run(ftl::Configurable *root) {
int N = root->value("N", 100); int N = root->value("N", 100);
// For each stream found, add a source object // For each stream found, add a source object
for (int i=0; i<=min(max_stream,N-1); ++i) { int count = min(max_stream+1, N);
for (int i=0; i<count; ++i) {
root->getConfig()["sources"].push_back(nlohmann::json{{"uri",std::string("file://") + path + std::string("#") + std::to_string(i)}}); root->getConfig()["sources"].push_back(nlohmann::json{{"uri",std::string("file://") + path + std::string("#") + std::to_string(i)}});
} }
sourcecounts.push_back(count);
} }
} }
...@@ -235,15 +246,15 @@ static void run(ftl::Configurable *root) { ...@@ -235,15 +246,15 @@ static void run(ftl::Configurable *root) {
} }
} }
ftl::rgbd::FrameSet scene_A; // Output of align process std::vector<ftl::rgbd::FrameSet> scene_A(sourcecounts.size()); // Output of align process
ftl::rgbd::FrameSet scene_B; // Input of render process std::vector<ftl::rgbd::FrameSet> scene_B(sourcecounts.size()); // Input of render process
//ftl::voxhash::SceneRep *scene = ftl::create<ftl::voxhash::SceneRep>(root, "voxelhash"); //ftl::voxhash::SceneRep *scene = ftl::create<ftl::voxhash::SceneRep>(root, "voxelhash");
ftl::rgbd::Streamer *stream = ftl::create<ftl::rgbd::Streamer>(root, "stream", net); ftl::rgbd::Streamer *stream = ftl::create<ftl::rgbd::Streamer>(root, "stream", net);
ftl::rgbd::VirtualSource *virt = ftl::create<ftl::rgbd::VirtualSource>(root, "virtual"); ftl::rgbd::VirtualSource *virt = ftl::create<ftl::rgbd::VirtualSource>(root, "virtual");
//root->set("tags", nlohmann::json::array({ root->getID()+"/virtual" })); //root->set("tags", nlohmann::json::array({ root->getID()+"/virtual" }));
ftl::render::Triangular *splat = ftl::create<ftl::render::Triangular>(root, "renderer", &scene_B); ftl::render::Triangular *splat = ftl::create<ftl::render::Triangular>(root, "renderer", &(scene_B[0]));
ftl::rgbd::Group *group = new ftl::rgbd::Group; std::vector<ftl::rgbd::Group *> groups;
ftl::ILW *align = ftl::create<ftl::ILW>(root, "merge"); ftl::ILW *align = ftl::create<ftl::ILW>(root, "merge");
int o = root->value("origin_pose", 0) % sources.size(); int o = root->value("origin_pose", 0) % sources.size();
...@@ -258,7 +269,7 @@ static void run(ftl::Configurable *root) { ...@@ -258,7 +269,7 @@ static void run(ftl::Configurable *root) {
//virt->setTimestamp(scene_B.timestamp); //virt->setTimestamp(scene_B.timestamp);
// Do we need to convert Lab to BGR? // Do we need to convert Lab to BGR?
if (align->isLabColour()) { if (align->isLabColour()) {
for (auto &f : scene_B.frames) { for (auto &f : scene_B[0].frames) {
auto &col = f.get<cv::cuda::GpuMat>(Channel::Colour); auto &col = f.get<cv::cuda::GpuMat>(Channel::Colour);
cv::cuda::cvtColor(col,col, cv::COLOR_Lab2BGR); // TODO: Add stream cv::cuda::cvtColor(col,col, cv::COLOR_Lab2BGR); // TODO: Add stream
} }
...@@ -268,28 +279,34 @@ static void run(ftl::Configurable *root) { ...@@ -268,28 +279,34 @@ static void run(ftl::Configurable *root) {
}); });
stream->add(virt); stream->add(virt);
for (size_t i=0; i<sources.size(); i++) { size_t cumulative = 0;
for (auto c : sourcecounts) {
auto group = new ftl::rgbd::Group;
for (size_t i=cumulative; i<cumulative+c; i++) {
Source *in = sources[i]; Source *in = sources[i];
in->setChannel(Channel::Depth); in->setChannel(Channel::Depth);
group->addSource(in); group->addSource(in);
} }
groups.push_back(group);
cumulative += c;
}
// ---- Recording code ----------------------------------------------------- // ---- Recording code -----------------------------------------------------
std::ofstream fileout; std::ofstream fileout;
ftl::codecs::Writer writer(fileout); ftl::codecs::Writer writer(fileout);
auto recorder = [&writer,&group](ftl::rgbd::Source *src, const ftl::codecs::StreamPacket &spkt, const ftl::codecs::Packet &pkt) { auto recorder = [&writer,&groups](ftl::rgbd::Source *src, const ftl::codecs::StreamPacket &spkt, const ftl::codecs::Packet &pkt) {
ftl::codecs::StreamPacket s = spkt; ftl::codecs::StreamPacket s = spkt;
// Patch stream ID to match order in group // Patch stream ID to match order in group
s.streamID = group->streamID(src); s.streamID = groups[0]->streamID(src);
writer.write(s, pkt); writer.write(s, pkt);
}; };
root->set("record", false); root->set("record", false);
// Allow stream recording // Allow stream recording
root->on("record", [&group,&fileout,&writer,&recorder](const ftl::config::Event &e) { root->on("record", [&groups,&fileout,&writer,&recorder](const ftl::config::Event &e) {
if (e.entity->value("record", false)) { if (e.entity->value("record", false)) {
char timestamp[18]; char timestamp[18];
std::time_t t=std::time(NULL); std::time_t t=std::time(NULL);
...@@ -297,17 +314,17 @@ static void run(ftl::Configurable *root) { ...@@ -297,17 +314,17 @@ static void run(ftl::Configurable *root) {
fileout.open(std::string(timestamp) + ".ftl"); fileout.open(std::string(timestamp) + ".ftl");
writer.begin(); writer.begin();
group->addRawCallback(std::function(recorder)); groups[0]->addRawCallback(std::function(recorder));
// TODO: Write pose+calibration+config packets // TODO: Write pose+calibration+config packets
auto sources = group->sources(); auto sources = groups[0]->sources();
for (size_t i=0; i<sources.size(); ++i) { for (size_t i=0; i<sources.size(); ++i) {
//writeSourceProperties(writer, i, sources[i]); //writeSourceProperties(writer, i, sources[i]);
sources[i]->inject(Channel::Calibration, sources[i]->parameters(), Channel::Left, sources[i]->getCapabilities()); sources[i]->inject(Channel::Calibration, sources[i]->parameters(), Channel::Left, sources[i]->getCapabilities());
sources[i]->inject(sources[i]->getPose()); sources[i]->inject(sources[i]->getPose());
} }
} else { } else {
group->removeRawCallback(recorder); groups[0]->removeRawCallback(recorder);
writer.end(); writer.end();
fileout.close(); fileout.close();
} }
...@@ -338,10 +355,11 @@ static void run(ftl::Configurable *root) { ...@@ -338,10 +355,11 @@ static void run(ftl::Configurable *root) {
pipeline1->append<ftl::operators::MultiViewMLS>("mvmls"); pipeline1->append<ftl::operators::MultiViewMLS>("mvmls");
// Alignment // Alignment
size_t size = groups.size();
group->setLatency(4); for (size_t i = 0; i < size; ++i) {
group->setName("ReconGroup"); groups[i]->setLatency(4);
group->sync([splat,virt,&busy,&slave,&scene_A,&scene_B,&align,controls,pipeline1](ftl::rgbd::FrameSet &fs) -> bool { groups[i]->setName("ReconGroup-" + std::to_string(i));
groups[i]->sync([splat,virt,&busy,&slave,&scene_A,&scene_B,&align,controls,pipeline1,i](ftl::rgbd::FrameSet &fs) -> bool {
//cudaSetDevice(scene->getCUDADevice()); //cudaSetDevice(scene->getCUDADevice());
//if (slave.isPaused()) return true; //if (slave.isPaused()) return true;
...@@ -354,27 +372,28 @@ static void run(ftl::Configurable *root) { ...@@ -354,27 +372,28 @@ static void run(ftl::Configurable *root) {
busy = true; busy = true;
// Swap the entire frameset to allow rapid return // Swap the entire frameset to allow rapid return
fs.swapTo(scene_A); fs.swapTo(scene_A[i]);
ftl::pool.push([&scene_B,&scene_A,&busy,&slave,&align, pipeline1](int id) { ftl::pool.push([&scene_B,&scene_A,&busy,&slave,&align,pipeline1,i](int id) {
//cudaSetDevice(scene->getCUDADevice()); //cudaSetDevice(scene->getCUDADevice());
// TODO: Release frameset here... // TODO: Release frameset here...
//cudaSafeCall(cudaStreamSynchronize(scene->getIntegrationStream())); //cudaSafeCall(cudaStreamSynchronize(scene->getIntegrationStream()));
UNIQUE_LOCK(scene_A.mtx, lk); UNIQUE_LOCK(scene_A[i].mtx, lk);
pipeline1->apply(scene_A, scene_A, 0); pipeline1->apply(scene_A[i], scene_A[i], 0);
align->process(scene_A); align->process(scene_A[i]);
// TODO: To use second GPU, could do a download, swap, device change, // TODO: To use second GPU, could do a download, swap, device change,
// then upload to other device. Or some direct device-2-device copy. // then upload to other device. Or some direct device-2-device copy.
scene_A.swapTo(scene_B); scene_A[i].swapTo(scene_B[i]);
LOG(INFO) << "Align complete... " << scene_A.timestamp; LOG(INFO) << "Align complete... " << scene_A[i].timestamp;
busy = false; busy = false;
}); });
return true; return true;
}); });
}
LOG(INFO) << "Start timer"; LOG(INFO) << "Start timer";
ftl::timer::start(true); ftl::timer::start(true);
...@@ -394,7 +413,9 @@ static void run(ftl::Configurable *root) { ...@@ -394,7 +413,9 @@ static void run(ftl::Configurable *root) {
delete stream; delete stream;
delete virt; delete virt;
delete net; delete net;
delete group; for (auto g : groups) {
delete g;
}
ftl::config::cleanup(); // Remove any last configurable objects. ftl::config::cleanup(); // Remove any last configurable objects.
LOG(INFO) << "Done."; LOG(INFO) << "Done.";
......
...@@ -581,9 +581,9 @@ Configurable *ftl::config::configure(int argc, char **argv, const std::string &r ...@@ -581,9 +581,9 @@ Configurable *ftl::config::configure(int argc, char **argv, const std::string &r
// Process Arguments // Process Arguments
auto options = ftl::config::read_options(&argv, &argc); auto options = ftl::config::read_options(&argv, &argc);
vector<string> paths; vector<string> paths(argc);
while (argc-- > 0) { while (argc-- > 0) {
paths.push_back(argv[0]); paths[argc] = argv[argc];
} }
if (!findConfiguration(options["config"], paths)) { if (!findConfiguration(options["config"], paths)) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment