update.
This commit is contained in:
parent
737f6a8fab
commit
56b48af3e8
2
.vscode/c_cpp_properties.json
vendored
2
.vscode/c_cpp_properties.json
vendored
@ -9,6 +9,8 @@
|
|||||||
"/opt/aarch64-v01c01-linux-gnu-gcc/lib/ZLMediaKit/include",
|
"/opt/aarch64-v01c01-linux-gnu-gcc/lib/ZLMediaKit/include",
|
||||||
"/opt/aarch64-v01c01-linux-gnu-gcc/lib/LeakTracer/include",
|
"/opt/aarch64-v01c01-linux-gnu-gcc/lib/LeakTracer/include",
|
||||||
"/opt/aarch64-v01c01-linux-gnu-gcc/lib/opencv-4.11.0/include/opencv4",
|
"/opt/aarch64-v01c01-linux-gnu-gcc/lib/opencv-4.11.0/include/opencv4",
|
||||||
|
"/opt/aarch64-v01c01-linux-gnu-gcc/lib/nng-1.10.1/include",
|
||||||
|
"build/_deps/ftxui-src/include",
|
||||||
"build/_deps/kylin-src"
|
"build/_deps/kylin-src"
|
||||||
],
|
],
|
||||||
"defines": [],
|
"defines": [],
|
||||||
|
@ -24,7 +24,8 @@ set(Boost_INCLUDE_DIR ${BOOST_ROOT}/include)
|
|||||||
set(Boost_USE_STATIC_LIBS ON)
|
set(Boost_USE_STATIC_LIBS ON)
|
||||||
find_package(Boost REQUIRED COMPONENTS log serialization)
|
find_package(Boost REQUIRED COMPONENTS log serialization)
|
||||||
|
|
||||||
set(MbedTLS_DIR ${Libraries_ROOT}/mbedtls-3.6.2/lib/cmake/MbedTLS)
|
set(MbedTLS_DIR ${Libraries_ROOT}/mbedtls-3.6.3/lib/cmake/MbedTLS)
|
||||||
|
set(nng_DIR ${Libraries_ROOT}/nng-1.10.1/lib/cmake/nng)
|
||||||
|
|
||||||
set(ZLMediaKit_ROOT /opt/aarch64-v01c01-linux-gnu-gcc/lib/ZLMediaKit)
|
set(ZLMediaKit_ROOT /opt/aarch64-v01c01-linux-gnu-gcc/lib/ZLMediaKit)
|
||||||
set(ZLMediaKit_INCLUDE_DIR ${ZLMediaKit_ROOT}/include)
|
set(ZLMediaKit_INCLUDE_DIR ${ZLMediaKit_ROOT}/include)
|
||||||
@ -41,4 +42,5 @@ FetchContent_Declare(Kylin
|
|||||||
GIT_REPOSITORY ssh://git@gitea.amass.fun:2022/amass/Kylin.git
|
GIT_REPOSITORY ssh://git@gitea.amass.fun:2022/amass/Kylin.git
|
||||||
)
|
)
|
||||||
set(ENABLE_ROUTER ON)
|
set(ENABLE_ROUTER ON)
|
||||||
|
set(ENABLE_NNG ON)
|
||||||
FetchContent_MakeAvailable(Kylin)
|
FetchContent_MakeAvailable(Kylin)
|
@ -7,6 +7,7 @@ add_executable(PassengerStatistics main.cpp
|
|||||||
Application.h Application.cpp
|
Application.h Application.cpp
|
||||||
Camera.h Camera.cpp
|
Camera.h Camera.cpp
|
||||||
ImageUtilities.h ImageUtilities.cpp
|
ImageUtilities.h ImageUtilities.cpp
|
||||||
|
NngServer.h NngServer.cpp
|
||||||
RtspServer.h RtspServer.cpp
|
RtspServer.h RtspServer.cpp
|
||||||
Settings.h Settings.cpp
|
Settings.h Settings.cpp
|
||||||
VideoInput.h VideoInput.cpp
|
VideoInput.h VideoInput.cpp
|
||||||
@ -38,6 +39,7 @@ target_link_directories(PassengerStatistics
|
|||||||
target_link_libraries(PassengerStatistics
|
target_link_libraries(PassengerStatistics
|
||||||
PRIVATE Kylin::Core
|
PRIVATE Kylin::Core
|
||||||
PRIVATE Kylin::Router
|
PRIVATE Kylin::Router
|
||||||
|
PRIVATE Kylin::Nng
|
||||||
PRIVATE LibDataChannel::LibDataChannel
|
PRIVATE LibDataChannel::LibDataChannel
|
||||||
PRIVATE OpenSSL::SSL
|
PRIVATE OpenSSL::SSL
|
||||||
PRIVATE OpenSSL::Crypto
|
PRIVATE OpenSSL::Crypto
|
||||||
|
@ -82,7 +82,7 @@ bool Camera::zoom(Zoom type) {
|
|||||||
autolens_param.Params.Param_Base.nSpeed = 10;
|
autolens_param.Params.Param_Base.nSpeed = 10;
|
||||||
int status = SensorSdk_AutoLens_SetParam(0, zoomType, &autolens_param);
|
int status = SensorSdk_AutoLens_SetParam(0, zoomType, &autolens_param);
|
||||||
|
|
||||||
std::this_thread::sleep_for(10ms);
|
std::this_thread::sleep_for(20ms);
|
||||||
|
|
||||||
autolens_param.Params.Param_Base.nStop = 1;
|
autolens_param.Params.Param_Base.nStop = 1;
|
||||||
autolens_param.Params.Param_Base.nSpeed = 0;
|
autolens_param.Params.Param_Base.nSpeed = 0;
|
||||||
|
54
Main/NngServer.cpp
Normal file
54
Main/NngServer.cpp
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
#include "NngServer.h"
|
||||||
|
#include "Camera.h"
|
||||||
|
#include "Core/Logger.h"
|
||||||
|
#include "Nng/SocketAisoWrapper.h"
|
||||||
|
#include <boost/asio/io_context.hpp>
|
||||||
|
#include <boost/json/object.hpp>
|
||||||
|
#include <boost/json/parse.hpp>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
NngServer::NngServer(boost::asio::io_context &ioContex) {
|
||||||
|
m_socket = std::make_shared<Nng::Asio::Socket>(ioContex, Nng::Reply);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NngServer::asyncRead() {
|
||||||
|
m_socket->asyncReceive([ptr{weak_from_this()}](const boost::system::error_code &error, const Nng::Buffer &buffer) {
|
||||||
|
if (error) {
|
||||||
|
LOG(error) << error.message();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (ptr.expired()) return;
|
||||||
|
auto self = ptr.lock();
|
||||||
|
std::error_code jsonError;
|
||||||
|
auto value = boost::json::parse(buffer.data<char>(), jsonError);
|
||||||
|
if (jsonError) {
|
||||||
|
LOG(error) << jsonError.message();
|
||||||
|
} else {
|
||||||
|
auto &request = value.as_object();
|
||||||
|
auto command = request.at("command").as_string();
|
||||||
|
LOG(info) << "command: " << command;
|
||||||
|
auto camera = Core::Singleton<Camera>::instance();
|
||||||
|
if (command == "ZeroCheck") {
|
||||||
|
|
||||||
|
camera->zeroCheck();
|
||||||
|
} else if (command == "Zoom") {
|
||||||
|
auto direction = request.at("direction").as_string();
|
||||||
|
camera->zoom(direction == "In" ? Camera::Zoom::In : Camera::Zoom::Out);
|
||||||
|
} else if (command == "Focus") {
|
||||||
|
auto direction = request.at("direction").as_string();
|
||||||
|
camera->focus(direction == "Far" ? Camera::Focus::Far : Camera::Focus::Near);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG(info) << "nng received: " << buffer.data<char>();
|
||||||
|
self->m_socket->send((void *)"world", strlen("world") + 1);
|
||||||
|
self->asyncRead();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void NngServer::start(uint16_t replyPort) {
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << "tcp://0.0.0.0:" << replyPort;
|
||||||
|
m_socket->listen(oss.str());
|
||||||
|
asyncRead();
|
||||||
|
}
|
34
Main/NngServer.h
Normal file
34
Main/NngServer.h
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
#ifndef __NNGSERVER_H__
|
||||||
|
#define __NNGSERVER_H__
|
||||||
|
|
||||||
|
#include "Core/Singleton.h"
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
namespace asio {
|
||||||
|
class io_context;
|
||||||
|
}
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
namespace Nng {
|
||||||
|
|
||||||
|
namespace Asio {
|
||||||
|
|
||||||
|
class Socket;
|
||||||
|
}
|
||||||
|
} // namespace Nng
|
||||||
|
|
||||||
|
class NngServer : public std::enable_shared_from_this<NngServer> {
|
||||||
|
friend class Core::Singleton<NngServer>;
|
||||||
|
|
||||||
|
public:
|
||||||
|
void start(uint16_t replyPort);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
NngServer(boost::asio::io_context &ioContex);
|
||||||
|
void asyncRead();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::shared_ptr<Nng::Asio::Socket> m_socket;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // __NNGSERVER_H__
|
@ -67,4 +67,8 @@ std::string Settings::sqlitePath() const {
|
|||||||
return m_sqlitePath;
|
return m_sqlitePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint16_t Settings::nngReplyPort() const {
|
||||||
|
return m_nngReplyPort;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Danki
|
} // namespace Danki
|
@ -16,6 +16,7 @@ public:
|
|||||||
uint16_t port() const;
|
uint16_t port() const;
|
||||||
std::string documentRoot() const;
|
std::string documentRoot() const;
|
||||||
std::string sqlitePath() const;
|
std::string sqlitePath() const;
|
||||||
|
uint16_t nngReplyPort() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint32_t m_threads = 1;
|
uint32_t m_threads = 1;
|
||||||
@ -24,6 +25,8 @@ private:
|
|||||||
|
|
||||||
std::string m_documentRoot = "/data/sdcard/PassengerStatistics/web";
|
std::string m_documentRoot = "/data/sdcard/PassengerStatistics/web";
|
||||||
std::string m_sqlitePath = "database.sqlite";
|
std::string m_sqlitePath = "database.sqlite";
|
||||||
|
|
||||||
|
uint16_t m_nngReplyPort = 8000;
|
||||||
};
|
};
|
||||||
} // namespace Danki
|
} // namespace Danki
|
||||||
|
|
||||||
|
@ -163,6 +163,7 @@ void Streamer::start(const std::string &signalServerAddress, uint16_t signalServ
|
|||||||
|
|
||||||
void Streamer::push(const uint8_t *data, uint32_t size) {
|
void Streamer::push(const uint8_t *data, uint32_t size) {
|
||||||
using namespace std::chrono;
|
using namespace std::chrono;
|
||||||
|
if (m_d->m_clients.empty()) return;
|
||||||
boost::asio::post(m_d->strand, [this, frame = rtc::binary(reinterpret_cast<const rtc::byte *>(data),
|
boost::asio::post(m_d->strand, [this, frame = rtc::binary(reinterpret_cast<const rtc::byte *>(data),
|
||||||
reinterpret_cast<const rtc::byte *>(data) + size)]() {
|
reinterpret_cast<const rtc::byte *>(data) + size)]() {
|
||||||
for (auto &[id, client] : m_d->m_clients) {
|
for (auto &[id, client] : m_d->m_clients) {
|
||||||
|
@ -4,7 +4,9 @@
|
|||||||
#include "Core/IoContext.h"
|
#include "Core/IoContext.h"
|
||||||
#include "Core/Logger.h"
|
#include "Core/Logger.h"
|
||||||
#include "Core/Singleton.h"
|
#include "Core/Singleton.h"
|
||||||
|
#include "NngServer.h"
|
||||||
#include "RtspServer.h"
|
#include "RtspServer.h"
|
||||||
|
#include "Settings.h"
|
||||||
#include "VideoInput.h"
|
#include "VideoInput.h"
|
||||||
#include "WebRTC/Streamer.h"
|
#include "WebRTC/Streamer.h"
|
||||||
#include "rw_mpp_api.h"
|
#include "rw_mpp_api.h"
|
||||||
@ -27,12 +29,16 @@ int main(int argc, char const *argv[]) try {
|
|||||||
});
|
});
|
||||||
|
|
||||||
auto application = Singleton<Application>::construct();
|
auto application = Singleton<Application>::construct();
|
||||||
|
auto settings = Singleton<Settings>::instance();
|
||||||
|
|
||||||
auto camera = Singleton<Camera>::construct();
|
auto camera = Singleton<Camera>::construct();
|
||||||
auto rtsp = std::make_shared<RtspServer>(application->ioContext());
|
auto rtsp = std::make_shared<RtspServer>(application->ioContext());
|
||||||
auto streamer = std::make_shared<Streamer>(application->ioContext());
|
auto streamer = std::make_shared<Streamer>(application->ioContext());
|
||||||
streamer->start("127.0.0.1", 80);
|
streamer->start("127.0.0.1", 80);
|
||||||
|
|
||||||
|
auto nng = Singleton<NngServer>::construct(application->ioContext());
|
||||||
|
nng->start(settings->nngReplyPort());
|
||||||
|
|
||||||
auto video = std::make_shared<VideoInput>(2592, 1536);
|
auto video = std::make_shared<VideoInput>(2592, 1536);
|
||||||
video->setPacketHandler([&](const uint8_t *data, uint32_t size) {
|
video->setPacketHandler([&](const uint8_t *data, uint32_t size) {
|
||||||
rtsp->push(data, size);
|
rtsp->push(data, size);
|
||||||
|
@ -1 +1,2 @@
|
|||||||
add_subdirectory(LeakTracer)
|
add_subdirectory(LeakTracer)
|
||||||
|
add_subdirectory(Controller)
|
23
Tools/Controller/CMakeLists.txt
Normal file
23
Tools/Controller/CMakeLists.txt
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
find_package(Boost COMPONENTS json REQUIRED)
|
||||||
|
|
||||||
|
add_executable(Controller
|
||||||
|
main.cpp
|
||||||
|
NngClient.h NngClient.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
include(FetchContent)
|
||||||
|
|
||||||
|
FetchContent_Declare(FTXUI
|
||||||
|
GIT_REPOSITORY https://github.com/ArthurSonzogni/FTXUI
|
||||||
|
GIT_TAG v6.1.8
|
||||||
|
)
|
||||||
|
FetchContent_MakeAvailable(FTXUI)
|
||||||
|
|
||||||
|
target_link_libraries(Controller
|
||||||
|
PRIVATE Kylin::Core
|
||||||
|
PRIVATE Kylin::Nng
|
||||||
|
PRIVATE ftxui::screen
|
||||||
|
PRIVATE ftxui::dom
|
||||||
|
PRIVATE ftxui::component
|
||||||
|
PRIVATE Boost::json
|
||||||
|
)
|
54
Tools/Controller/NngClient.cpp
Normal file
54
Tools/Controller/NngClient.cpp
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
#include "NngClient.h"
|
||||||
|
#include "Core/Logger.h"
|
||||||
|
#include "Nng/SocketAisoWrapper.h"
|
||||||
|
#include <boost/json/object.hpp>
|
||||||
|
#include <boost/json/serialize.hpp>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
NngClient::NngClient(boost::asio::io_context &ioContex) {
|
||||||
|
m_socket = std::make_shared<Nng::Asio::Socket>(ioContex, Nng::Request);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NngClient::asyncRead() {
|
||||||
|
m_socket->asyncReceive([ptr{weak_from_this()}](const boost::system::error_code &error, const Nng::Buffer &buffer) {
|
||||||
|
if (error) {
|
||||||
|
LOG(error) << error.message();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (ptr.expired()) return;
|
||||||
|
auto self = ptr.lock();
|
||||||
|
// LOG(info) << "nng received: " << buffer.data<char>();
|
||||||
|
self->asyncRead();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void NngClient::start(const std::string &server, uint16_t port) {
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << "tcp://" << server << ":" << port;
|
||||||
|
std::error_code error;
|
||||||
|
m_socket->dial(oss.str(), error);
|
||||||
|
asyncRead();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NngClient::requestZeroCheck() {
|
||||||
|
boost::json::object request;
|
||||||
|
request["command"] = "ZeroCheck";
|
||||||
|
auto json = boost::json::serialize(request);
|
||||||
|
m_socket->send(json.data(), json.size() + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NngClient::requestZoom(bool in) {
|
||||||
|
boost::json::object request;
|
||||||
|
request["command"] = "Zoom";
|
||||||
|
request["direction"] = in ? "In" : "Out";
|
||||||
|
auto json = boost::json::serialize(request);
|
||||||
|
m_socket->send(json.data(), json.size() + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NngClient::requestFocus(bool far) {
|
||||||
|
boost::json::object request;
|
||||||
|
request["command"] = "Focus";
|
||||||
|
request["direction"] = far ? "Far" : "Near";
|
||||||
|
auto json = boost::json::serialize(request);
|
||||||
|
m_socket->send(json.data(), json.size() + 1);
|
||||||
|
}
|
38
Tools/Controller/NngClient.h
Normal file
38
Tools/Controller/NngClient.h
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
#ifndef __NNGCLIENT_H__
|
||||||
|
#define __NNGCLIENT_H__
|
||||||
|
|
||||||
|
#include "Core/Singleton.h"
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
namespace asio {
|
||||||
|
class io_context;
|
||||||
|
}
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
namespace Nng {
|
||||||
|
|
||||||
|
namespace Asio {
|
||||||
|
|
||||||
|
class Socket;
|
||||||
|
}
|
||||||
|
} // namespace Nng
|
||||||
|
|
||||||
|
class NngClient : public std::enable_shared_from_this<NngClient> {
|
||||||
|
friend class Core::Singleton<NngClient>;
|
||||||
|
|
||||||
|
public:
|
||||||
|
void start(const std::string &server, uint16_t port);
|
||||||
|
void requestZeroCheck();
|
||||||
|
void requestZoom(bool in);
|
||||||
|
void requestFocus(bool far);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
NngClient(boost::asio::io_context &ioContex);
|
||||||
|
void asyncRead();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::shared_ptr<Nng::Asio::Socket> m_socket;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // __NNGCLIENT_H__
|
60
Tools/Controller/main.cpp
Normal file
60
Tools/Controller/main.cpp
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
#include "Core/IoContext.h"
|
||||||
|
#include "Core/Singleton.h"
|
||||||
|
#include "NngClient.h"
|
||||||
|
#include <ftxui/component/component.hpp>
|
||||||
|
#include <ftxui/component/screen_interactive.hpp>
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
using namespace Core;
|
||||||
|
auto ioContext = Singleton<IoContext>::construct(std::thread::hardware_concurrency());
|
||||||
|
auto nng = Singleton<NngClient>::construct(*ioContext->ioContext());
|
||||||
|
nng->start("127.0.0.1", 8000);
|
||||||
|
|
||||||
|
auto zeroCheckButton =
|
||||||
|
ftxui::Button("零点校正", [&]() { nng->requestZeroCheck(); }, ftxui::ButtonOption::Animated());
|
||||||
|
|
||||||
|
auto zoomButtons = ftxui::Container::Horizontal({
|
||||||
|
ftxui::Button(
|
||||||
|
"+", [&]() { nng->requestZoom(false); }, ftxui::ButtonOption::Animated()),
|
||||||
|
ftxui::Button(
|
||||||
|
"-", [&]() { nng->requestZoom(true); }, ftxui::ButtonOption::Animated()),
|
||||||
|
});
|
||||||
|
auto zoomItem = ftxui::Renderer(zoomButtons, [&]() {
|
||||||
|
return ftxui::hbox({
|
||||||
|
ftxui::text("zoom:") | ftxui::vcenter,
|
||||||
|
zoomButtons->Render(),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
auto focusButtons = ftxui::Container::Horizontal({
|
||||||
|
ftxui::Button(
|
||||||
|
"+", [&]() { nng->requestFocus(true); }, ftxui::ButtonOption::Animated()),
|
||||||
|
ftxui::Button(
|
||||||
|
"-", [&]() { nng->requestFocus(false); }, ftxui::ButtonOption::Animated()),
|
||||||
|
});
|
||||||
|
auto focusItem = ftxui::Renderer(focusButtons, [&]() {
|
||||||
|
return ftxui::hbox({
|
||||||
|
ftxui::text("focus:") | ftxui::vcenter,
|
||||||
|
focusButtons->Render(),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
auto controls = ftxui::Container::Vertical({
|
||||||
|
zeroCheckButton,
|
||||||
|
zoomItem,
|
||||||
|
focusItem,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Modify the way to render them on screen:
|
||||||
|
auto component = ftxui::Renderer(controls, [&] {
|
||||||
|
return ftxui::vbox({
|
||||||
|
ftxui::text("Nng 控制端"),
|
||||||
|
controls->Render(),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
ioContext->run(false);
|
||||||
|
auto screen = ftxui::ScreenInteractive::FitComponent();
|
||||||
|
screen.Loop(component);
|
||||||
|
return 0;
|
||||||
|
}
|
@ -96,6 +96,7 @@ function deploy() {
|
|||||||
echo "deploy to target, path: ${TARGET_PATH} ..."
|
echo "deploy to target, path: ${TARGET_PATH} ..."
|
||||||
echo "put ${build_path}/Main/PassengerStatistics ${TARGET_PATH}" | sftp danki
|
echo "put ${build_path}/Main/PassengerStatistics ${TARGET_PATH}" | sftp danki
|
||||||
echo "put ${build_path}/Tools/LeakTracer/LeakTracer ${TARGET_PATH}" | sftp danki
|
echo "put ${build_path}/Tools/LeakTracer/LeakTracer ${TARGET_PATH}" | sftp danki
|
||||||
|
echo "put ${build_path}/Tools/Controller/Controller ${TARGET_PATH}" | sftp danki
|
||||||
ssh danki "sync"
|
ssh danki "sync"
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user