127 lines
3.9 KiB
C++
127 lines
3.9 KiB
C++
#include "app/lidar_manager_app.hpp"
|
|
|
|
#include "auth/auth_service.hpp"
|
|
#include "mission/mission_enqueue.hpp"
|
|
#include "mission/mission_queue.hpp"
|
|
#include "mission/mission_scheduler.hpp"
|
|
#include "mission/mission_store.hpp"
|
|
#include "mission/modbus_trigger_service.hpp"
|
|
#include "robot/robot_runtime.hpp"
|
|
#include "server/api_server.hpp"
|
|
#include "server/static_file_server.hpp"
|
|
#include "storage/dashboard_store.hpp"
|
|
#include "storage/database.hpp"
|
|
#include "storage/map_store.hpp"
|
|
#include "storage/site_store.hpp"
|
|
#include "storage/sound_store.hpp"
|
|
#include "storage/transition_store.hpp"
|
|
#include "storage/state_repository.hpp"
|
|
|
|
#include <httplib.h>
|
|
#include <cstdio>
|
|
|
|
namespace lm {
|
|
|
|
namespace {
|
|
|
|
bool isProjectRootDataPath(const std::filesystem::path& parent)
|
|
{
|
|
return parent.empty() || parent == std::filesystem::path(".");
|
|
}
|
|
|
|
std::filesystem::path resolveDataPath(std::filesystem::path data_path)
|
|
{
|
|
if (!isProjectRootDataPath(data_path.parent_path()))
|
|
return data_path;
|
|
if (data_path.filename() == "state.json")
|
|
return std::filesystem::path("data") / "state.json";
|
|
return std::filesystem::path("data") / "RBS.db";
|
|
}
|
|
|
|
} // namespace
|
|
|
|
LidarManagerApp::LidarManagerApp(int port,
|
|
std::filesystem::path www_root,
|
|
std::filesystem::path data_path)
|
|
: port_(port), www_root_(std::move(www_root)), data_path_(std::move(data_path))
|
|
{
|
|
}
|
|
|
|
int LidarManagerApp::run()
|
|
{
|
|
data_path_ = resolveDataPath(data_path_);
|
|
const std::filesystem::path data_dir = data_path_.parent_path();
|
|
Database database(data_dir);
|
|
std::string db_err;
|
|
if (!database.init(db_err))
|
|
{
|
|
std::fprintf(stderr, "database init failed: %s\n", db_err.c_str());
|
|
return 1;
|
|
}
|
|
|
|
StateRepository repo(data_path_, database);
|
|
repo.load();
|
|
|
|
MapStore map_store(database);
|
|
TransitionStore transition_store(database);
|
|
MissionStore mission_store(database);
|
|
MissionQueue mission_queue(database, map_store, transition_store, mission_store);
|
|
RobotRuntime robot_runtime(database, mission_queue);
|
|
SiteStore site_store(database);
|
|
site_store.ensureDefaultSiteId();
|
|
SoundStore sound_store(database);
|
|
{
|
|
std::string sound_err;
|
|
if (!sound_store.ensureSystemDefaults(sound_err))
|
|
std::fprintf(stderr, "Warning: sound defaults: %s\n", sound_err.c_str());
|
|
}
|
|
DashboardStore dashboard_store(database);
|
|
|
|
const auto enqueue_fn = [&mission_store, &mission_queue](const nlohmann::json& request, std::string& err) -> bool {
|
|
nlohmann::json payload;
|
|
if (!MissionEnqueue::buildPayload(mission_store, request, payload, err))
|
|
return false;
|
|
return static_cast<bool>(mission_queue.enqueue(payload, err));
|
|
};
|
|
|
|
ModbusTriggerService modbus(mission_store, enqueue_fn, 5502);
|
|
MissionScheduler scheduler(mission_store, enqueue_fn);
|
|
|
|
AuthService auth(database);
|
|
|
|
httplib::Server svr;
|
|
svr.set_pre_routing_handler([&auth](const httplib::Request& req, httplib::Response& res) {
|
|
return auth.preRoute(req, res);
|
|
});
|
|
|
|
ApiServer api(repo,
|
|
mission_queue,
|
|
mission_store,
|
|
modbus,
|
|
scheduler,
|
|
robot_runtime,
|
|
map_store,
|
|
site_store,
|
|
sound_store,
|
|
transition_store,
|
|
dashboard_store);
|
|
api.registerRoutes(svr);
|
|
auth.registerRoutes(svr);
|
|
StaticFileServer::mount(svr, www_root_);
|
|
|
|
std::fprintf(stderr,
|
|
"lidar_manager_web listening on http://0.0.0.0:%d (www=%s, db=%s, maps=%s, sounds=%s)\n",
|
|
port_,
|
|
www_root_.string().c_str(),
|
|
database.dbPath().string().c_str(),
|
|
database.mapsDir().string().c_str(),
|
|
database.soundsDir().string().c_str());
|
|
std::fprintf(stderr, "MiR REST API: http://0.0.0.0:%d/api/v2.0.0/mission_queue\n", port_);
|
|
std::fprintf(stderr, "Modbus TCP triggers: port 5502 (coils 1001-2000)\n");
|
|
|
|
svr.listen("0.0.0.0", port_);
|
|
return 0;
|
|
}
|
|
|
|
} // namespace lm
|