Skip to content

Commit

Permalink
multiple streams now working, update syntax
Browse files Browse the repository at this point in the history
  • Loading branch information
S1ink committed Jul 1, 2022
1 parent 3cbb25b commit f3fbb72
Show file tree
Hide file tree
Showing 14 changed files with 444 additions and 363 deletions.
Binary file modified lib-vs/obj/visioncamera.cpp.pic.o
Binary file not shown.
4 changes: 3 additions & 1 deletion lib-vs/obj/visionserver2.cpp.pic.d
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ obj/visionserver2.cpp.pic.o: src\core/visionserver2.cpp \
include/cscore.h include/cscore_c.h include/cscore_cpp.h \
include/cscore_oo.h include/cscore_oo.inc include/cscore_cv.h \
include/cameraserver/CameraServer.inc include/wpi/json.h \
src\core/visionserver2.inc
src\core/visionserver2.inc additions/cpp-tools/src/resources.h

src\core/visionserver2.h:

Expand Down Expand Up @@ -411,3 +411,5 @@ include/cameraserver/CameraServer.inc:
include/wpi/json.h:

src\core/visionserver2.inc:

additions/cpp-tools/src/resources.h:
Binary file modified lib-vs/obj/visionserver2.cpp.pic.o
Binary file not shown.
12 changes: 7 additions & 5 deletions lib-vs/out/include/target.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
#include <string>

#include <opencv2/opencv.hpp>

#include <networktables/NetworkTable.h>

#include "cpp-tools/src/types.h"

#include "visionserver2.h"


Expand All @@ -19,12 +19,14 @@ namespace vs2 {
*/
class Target {
public:
// inline static const std::shared_ptr<nt::NetworkTable>
// target_table{VisionServer::getTable()->GetSubTable("Targets")};
inline static const std::shared_ptr<nt::NetworkTable>& ntable() {
static std::shared_ptr<nt::NetworkTable> targets{VisionServer::ntable()->GetSubTable("Targets")};
return targets;
}

Target() = delete;
inline Target(const std::string& n) : name(n), table(VisionServer::targetsTable()->GetSubTable(this->name)) {}
inline Target(std::string&& n) : name(std::move(n)), table(VisionServer::targetsTable()->GetSubTable(this->name)) {}
inline Target(const std::string& n) : name(n), table(Target::ntable()->GetSubTable(this->name)) {}
inline Target(std::string&& n) : name(std::move(n)), table(Target::ntable()->GetSubTable(this->name)) {}
Target(const Target&) = default;
Target(Target&&) = default;

Expand Down
2 changes: 1 addition & 1 deletion lib-vs/out/include/visioncamera.h
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ class VisionCamera final: public cs::VideoCamera {
* Set the root networktable in which the camera's own networktable should reside
* @param table The root table (the camera resides in ~table~/Cameras)
*/
void setNetworkBase(std::shared_ptr<nt::NetworkTable> table);
void setNetworkBase(const std::shared_ptr<nt::NetworkTable>& table);
/**
* Publish networktables-adjustable settings for exposure, brightness, and whitebalance under the camera's networktable
*/
Expand Down
109 changes: 53 additions & 56 deletions lib-vs/out/include/visionserver2.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,14 @@
#include <string>
#include <atomic>
#include <thread>
#include <mutex>
#include <chrono>
#include <initializer_list>

#include <opencv2/opencv.hpp>

#include <networktables/NetworkTable.h>

#include "cpp-tools/src/types.h"

#include "visioncamera.h"


Expand All @@ -20,8 +19,10 @@ namespace vs2 {
class VisionServer final {
struct OutputStream;
public:
// inline static const std::shared_ptr<nt::NetworkTable>
// base_table{nt::NetworkTableInstance::GetDefault().GetTable("Vision Server")};
inline static const std::shared_ptr<nt::NetworkTable>& ntable() {
static std::shared_ptr<nt::NetworkTable> base{nt::NetworkTableInstance::GetDefault().GetTable("Vision Server")};
return base;
}

inline static void Init() {
getInstance();
Expand All @@ -30,33 +31,31 @@ class VisionServer final {
static VisionServer instance;
return instance;
}
inline static std::shared_ptr<nt::NetworkTable> getTable() { return inst().base; }
inline static std::shared_ptr<nt::NetworkTable> pipesTable() { return inst().pipes; }
inline static std::shared_ptr<nt::NetworkTable> streamsTable() { return inst().outputs; }
inline static std::shared_ptr<nt::NetworkTable> targetsTable() { return inst().targets; }


class BasePipe : public cs::CvSource {
friend class VisionServer;
public:
// inline static const std::shared_ptr<nt::NetworkTable>
// pipe_table{VisionServer::base_table->GetSubTable("Pipelines")};
inline static const std::shared_ptr<nt::NetworkTable>& ntable() {
static std::shared_ptr<nt::NetworkTable> pipes{VisionServer::ntable()->GetSubTable("Pipelines")};
return pipes;
}

inline const std::string& getName() const { return this->name; }
inline const std::shared_ptr<nt::NetworkTable> getTable() const { return this->table; }
inline const std::shared_ptr<nt::NetworkTable>& getTable() const { return this->table; }

virtual void process(cv::Mat& io_frame) = 0;

protected:
inline BasePipe(const char* name) : /* start enable/disable callback for more efficent threading */
CvSource(name, cs::VideoMode()), name(name),
input(this->name), table(pipesTable()->GetSubTable(this->name)) {}
input(this->name), table(BasePipe::ntable()->GetSubTable(this->name)) {}
inline BasePipe(const std::string& name) :
CvSource(name, cs::VideoMode()), name(name),
input(this->name), table(pipesTable()->GetSubTable(this->name)) {}
input(this->name), table(BasePipe::ntable()->GetSubTable(this->name)) {}
inline BasePipe(std::string&& name) :
CvSource(name, cs::VideoMode()), name(name),
input(this->name), table(pipesTable()->GetSubTable(this->name)) {}
input(this->name), table(BasePipe::ntable()->GetSubTable(this->name)) {}
BasePipe() = delete;


Expand All @@ -80,47 +79,49 @@ class VisionServer final {
};


static void addCamera(VisionCamera&&);
static void addCameras(std::vector<VisionCamera>&&);
static void setCameras(std::vector<VisionCamera>&&);
static bool addCamera(VisionCamera&&);
static bool addCameras(std::vector<VisionCamera>&&);
static bool setCameras(std::vector<VisionCamera>&&);
static const std::vector<VisionCamera>& getCameras();
static size_t numCameras();

template<class pipeline>
static void addPipeline();
static void addPipeline(BasePipe*);
static bool addPipeline();
static bool addPipeline(BasePipe*);
template<class... pipelines>
static void addPipelines();
static void addPipelines(std::vector<BasePipe*>&&);
static void addPipelines(std::initializer_list<BasePipe*>);
static bool addPipelines();
static bool addPipelines(std::vector<BasePipe*>&&);
static bool addPipelines(std::initializer_list<BasePipe*>);
template<class... pipelines>
static void setPipelines();
static void setPipelines(std::vector<BasePipe*>&&);
static void setPipelines(std::initializer_list<BasePipe*>);
static bool setPipelines();
static bool setPipelines(std::vector<BasePipe*>&&);
static bool setPipelines(std::initializer_list<BasePipe*>);
static const std::vector<BasePipe*>& getPipelines();
static size_t numPipelines();

static void addStream();
static void addStream(std::string_view);
static void addStream(std::string_view, int port);
static void addStream(const cs::MjpegServer&);
static void addStream(cs::MjpegServer&&);
static void addStreams(size_t = 2);
static void addStreams(std::initializer_list<std::string_view>);
static void addStreams(std::initializer_list<std::pair<std::string_view, int> >);
static void addStreams(const std::vector<cs::MjpegServer>&);
static bool addStream();
static bool addStream(std::string_view);
static bool addStream(std::string_view, int port);
static bool addStream(const cs::MjpegServer&);
static bool addStream(cs::MjpegServer&&);
static bool addStreams(size_t = 2);
static bool addStreams(std::initializer_list<std::string_view>);
static bool addStreams(std::initializer_list<std::pair<std::string_view, int> >);
static bool addStreams(const std::vector<cs::MjpegServer>&);
static const std::vector<OutputStream>& getStreams();
static size_t numStreams();

static void compensate(); // attempts to attach all pipelines to the first available camera, and all outputs to the first available source
static bool compensate(); // attempts to attach all pipelines to the first available camera, and all outputs to the first available source
static bool runRaw(); // run stream index handling for raw inputs (no processing, just camera feeds) - stops when processing is started
static bool runRawThread(); // run stream index handling in a separate thread - stops when processing is started

static bool run(uint16_t rps = 50);
static bool runSingle(uint16_t rps = 50); // runs in vs1 mode
static bool runThread(uint16_t rps = 50);
static bool runSingleThread(uint16_t rps = 50);
static bool run(uint16_t rps = 50); // start multithreaded processing - blocks until stop() is called [in another thread]
static bool runSingle(uint16_t rps = 50); // start singlethreaded processing - blocks until stop() is called [in another thread]
static bool runThread(uint16_t rps = 50); // start multithreaded processing in a separate thread - does not block
static bool runSingleThread(uint16_t rps = 50); // start singlethreaded processing in a separate thread - does not block
static bool isRunning();
static bool stop();
static inline void stopExit() { stop(); }
static bool stop(); // stop processing - returns if any instances were actually stopped
static inline void stopExit() { stop(); } // a void-returning wrapper for stop() to be used within 'atexit'


template<class pipeline = void, class... pipelines>
Expand All @@ -139,45 +140,41 @@ class VisionServer final {
void operator=(const VisionServer&) = delete;
void operator=(VisionServer&&) = delete;

//inline static VisionServer* _inst{nullptr};

std::vector<VisionCamera> cameras;
std::vector<BasePipe*> pipelines;
std::vector<OutputStream> streams;
std::vector<std::unique_ptr<BasePipe> > heap_allocated;

std::shared_ptr<nt::NetworkTable>
base, pipes, outputs, targets
;
std::vector<OutputStream> streams;

std::thread head;
std::atomic<bool> is_running{false};

struct OutputStream : public cs::MjpegServer {
friend class VisionServer;
public:
// inline static std::shared_ptr<nt::NetworkTable> streamsTable() {
// static std::shared_ptr<nt::NetworkTable> st{VisionServer::base_table->GetSubTable("Streams")};
// return st;
// }
inline static const std::shared_ptr<nt::NetworkTable>& ntable() {
static std::shared_ptr<nt::NetworkTable> streams{VisionServer::ntable()->GetSubTable("Streams")};
return streams;
}

OutputStream(cs::MjpegServer&& s);
inline OutputStream(std::string_view n) :
OutputStream(frc::CameraServer::AddServer(n)) {}
inline OutputStream(std::string_view n, int p) :
OutputStream(frc::CameraServer::AddServer(n, p)) {}
OutputStream(cs::MjpegServer&& s); // setup ntable values
inline OutputStream(const OutputStream& o) : table(o.table), local_idx(o.local_idx.load()) {}
inline OutputStream(const OutputStream& o) :
MjpegServer(o), table(o.table), local_idx(o.local_idx.load()) {}
inline OutputStream(OutputStream&& o) :
MjpegServer(std::move(o)), table(std::move(o.table)), local_idx(o.local_idx.load()) {}
~OutputStream();

void setSourceIdx(int i);
inline void setPipelineIdx(uint16_t i) { this->setSourceIdx(i); }
inline void setCameraIdx(uint16_t i) { this->setSourceIdx(-(int)i); }

protected:
void updateNt();
void syncIdx();

private:
// try storing MjpegServer instead of extending?
const std::shared_ptr<nt::NetworkTable> table;
std::atomic_int local_idx{0};

Expand Down
48 changes: 28 additions & 20 deletions lib-vs/out/include/visionserver2.inc
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
#include <sstream>


//using namespace vs2;
namespace vs2 {

inline const std::vector<VisionCamera>& VisionServer::getCameras() { return inst().cameras; }
Expand All @@ -16,37 +15,46 @@ inline size_t VisionServer::numStreams() { return inst().streams.size(); }
inline bool VisionServer::isRunning() { return inst().is_running; }

template<class pipeline>
void VisionServer::addPipeline() {
bool VisionServer::addPipeline() {
static_assert(std::is_base_of<VisionServer::BasePipe, pipeline>::value, "Template argument (pipeline) must inherit from BasePipe");
static_assert(std::is_default_constructible<pipeline>::value, "Template arguement (pipeline) must be default constructible");
if(!inst().is_running) {
inst().heap_allocated.emplace_back(std::make_unique<pipeline>());
inst().pipelines.push_back(inst().heap_allocated.back().get());
if(!VisionServer::isRunning()) {
VisionServer& _inst = getInstance();
_inst.heap_allocated.emplace_back(std::make_unique<pipeline>());
_inst.pipelines.push_back(_inst.heap_allocated.back().get());
return true;
}
return false;
}
template<class... pipelines_t>
void VisionServer::addPipelines() {
if(!inst().is_running) {
inst().heap_allocated.reserve(inst().heap_allocated.size() + sizeof...(pipelines_t));
inst().pipelines.reserve(inst().pipelines.size() + sizeof...(pipelines_t));
bool VisionServer::addPipelines() {
if(!VisionServer::isRunning()) {
VisionServer& _inst = getInstance();
_inst.heap_allocated.reserve(_inst.heap_allocated.size() + sizeof...(pipelines_t));
_inst.pipelines.reserve(_inst.pipelines.size() + sizeof...(pipelines_t));
size_t alloc = VisionServer::pipeExpander<pipelines_t...>(inst().heap_allocated);
for(size_t i = alloc; i >= 0; --i) {
inst().pipelines.push_back(inst().heap_allocated.at(inst().heap_allocated.size() - i - 1).get());
_inst.pipelines.push_back(_inst.heap_allocated.at(_inst.heap_allocated.size() - i - 1).get());
}
return true;
}
return false;
}
template<class... pipelines_t>
void VisionServer::setPipelines() {
if(!inst().is_running) {
inst().heap_allocated.clear();
inst().heap_allocated.reserve(sizeof...(pipelines_t));
inst().pipelines.clear();
inst().pipelines.reserve(sizeof...(pipelines_t));
VisionServer::pipeExpander<pipelines_t...>(inst().heap_allocated);
for(size_t i = 0; i < inst().heap_allocated.size(); i++) {
inst().pipelines.push_back(inst().heap_allocated.at(i).get());
bool VisionServer::setPipelines() {
if(!VisionServer::isRunning()) {
VisionServer& _inst = getInstance();
_inst.heap_allocated.clear();
_inst.heap_allocated.reserve(sizeof...(pipelines_t));
_inst.pipelines.clear();
_inst.pipelines.reserve(sizeof...(pipelines_t));
VisionServer::pipeExpander<pipelines_t...>(_inst.heap_allocated);
for(size_t i = 0; i < _inst.heap_allocated.size(); i++) {
_inst.pipelines.push_back(_inst.heap_allocated.at(i).get());
}
return true;
}
return false;
}

template<class pipeline, class... pipelines>
Expand Down Expand Up @@ -96,4 +104,4 @@ void SequentialPipeline<pipelines_t...>::process(cv::Mat& io_frame) {
}
}

}
} // namespace vs2;
Binary file modified lib-vs/out/libvs3407.so
Binary file not shown.
12 changes: 7 additions & 5 deletions lib-vs/src/core/target.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
#include <string>

#include <opencv2/opencv.hpp>

#include <networktables/NetworkTable.h>

#include "cpp-tools/src/types.h"

#include "visionserver2.h"


Expand All @@ -19,12 +19,14 @@ namespace vs2 {
*/
class Target {
public:
// inline static const std::shared_ptr<nt::NetworkTable>
// target_table{VisionServer::getTable()->GetSubTable("Targets")};
inline static const std::shared_ptr<nt::NetworkTable>& ntable() {
static std::shared_ptr<nt::NetworkTable> targets{VisionServer::ntable()->GetSubTable("Targets")};
return targets;
}

Target() = delete;
inline Target(const std::string& n) : name(n), table(VisionServer::targetsTable()->GetSubTable(this->name)) {}
inline Target(std::string&& n) : name(std::move(n)), table(VisionServer::targetsTable()->GetSubTable(this->name)) {}
inline Target(const std::string& n) : name(n), table(Target::ntable()->GetSubTable(this->name)) {}
inline Target(std::string&& n) : name(std::move(n)), table(Target::ntable()->GetSubTable(this->name)) {}
Target(const Target&) = default;
Target(Target&&) = default;

Expand Down
2 changes: 1 addition & 1 deletion lib-vs/src/core/visioncamera.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ void VisionCamera::setExposure(int8_t val) {
this->exposure = (val > 100 ? 100 : val);
}

void VisionCamera::setNetworkBase(std::shared_ptr<nt::NetworkTable> table) {
void VisionCamera::setNetworkBase(const std::shared_ptr<nt::NetworkTable>& table) {
this->camera = table->GetSubTable("Cameras")->GetSubTable(this->GetName());
}
void VisionCamera::setNetworkAdjustable() {
Expand Down
2 changes: 1 addition & 1 deletion lib-vs/src/core/visioncamera.h
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ class VisionCamera final: public cs::VideoCamera {
* Set the root networktable in which the camera's own networktable should reside
* @param table The root table (the camera resides in ~table~/Cameras)
*/
void setNetworkBase(std::shared_ptr<nt::NetworkTable> table);
void setNetworkBase(const std::shared_ptr<nt::NetworkTable>& table);
/**
* Publish networktables-adjustable settings for exposure, brightness, and whitebalance under the camera's networktable
*/
Expand Down
Loading

0 comments on commit f3fbb72

Please sign in to comment.