forked from IQ.Lvbs/IQ.Pilot
IQ.Pilot Release Commit @ 0798119
This commit is contained in:
193
tools/jotpluggler/common.cc
Normal file
193
tools/jotpluggler/common.cc
Normal file
@@ -0,0 +1,193 @@
|
||||
#include "tools/jotpluggler/common.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
|
||||
namespace {
|
||||
|
||||
std::string format_coord(const GpsPoint &point) {
|
||||
return util::string_format("%.5f,%.5f", point.lat, point.lon);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
const CameraViewSpec &camera_view_spec(CameraViewKind view) {
|
||||
auto it = std::find_if(kCameraViewSpecs.begin(), kCameraViewSpecs.end(), [&](const CameraViewSpec &spec) {
|
||||
return spec.view == view;
|
||||
});
|
||||
return it != kCameraViewSpecs.end() ? *it : kCameraViewSpecs.front();
|
||||
}
|
||||
|
||||
const CameraViewSpec *camera_view_spec_from_special_item(std::string_view item_id) {
|
||||
auto it = std::find_if(kCameraViewSpecs.begin(), kCameraViewSpecs.end(), [&](const CameraViewSpec &spec) {
|
||||
return item_id == spec.special_item_id;
|
||||
});
|
||||
return it != kCameraViewSpecs.end() ? &*it : nullptr;
|
||||
}
|
||||
|
||||
const CameraViewSpec *camera_view_spec_from_layout_name(std::string_view layout_name) {
|
||||
auto it = std::find_if(kCameraViewSpecs.begin(), kCameraViewSpecs.end(), [&](const CameraViewSpec &spec) {
|
||||
return layout_name == spec.layout_name;
|
||||
});
|
||||
return it != kCameraViewSpecs.end() ? &*it : nullptr;
|
||||
}
|
||||
|
||||
const SpecialItemSpec *special_item_spec(std::string_view item_id) {
|
||||
auto it = std::find_if(kSpecialItemSpecs.begin(), kSpecialItemSpecs.end(), [&](const SpecialItemSpec &spec) {
|
||||
return item_id == spec.id;
|
||||
});
|
||||
return it != kSpecialItemSpecs.end() ? &*it : nullptr;
|
||||
}
|
||||
|
||||
const char *special_item_label(std::string_view item_id) {
|
||||
const SpecialItemSpec *spec = special_item_spec(item_id);
|
||||
return spec != nullptr ? spec->label : "Item";
|
||||
}
|
||||
|
||||
bool pane_kind_is_special(PaneKind kind) {
|
||||
return kind == PaneKind::Map || kind == PaneKind::Camera;
|
||||
}
|
||||
|
||||
bool is_default_special_title(std::string_view title) {
|
||||
if (title == "Map") return true;
|
||||
return std::any_of(kCameraViewSpecs.begin(), kCameraViewSpecs.end(), [&](const CameraViewSpec &spec) {
|
||||
return title == spec.label;
|
||||
});
|
||||
}
|
||||
|
||||
CameraViewKind sidebar_preview_camera_view(const AppSession &session) {
|
||||
return session.route_data.road_camera.entries.empty() && !session.route_data.qroad_camera.entries.empty()
|
||||
? CameraViewKind::QRoad
|
||||
: CameraViewKind::Road;
|
||||
}
|
||||
|
||||
const std::filesystem::path &repo_root() {
|
||||
static const std::filesystem::path root(JOTP_REPO_ROOT);
|
||||
return root;
|
||||
}
|
||||
|
||||
ImU32 timeline_entry_color(TimelineEntry::Type type, float alpha) {
|
||||
return timeline_entry_color(type, alpha, {111, 143, 175});
|
||||
}
|
||||
|
||||
ImU32 timeline_entry_color(TimelineEntry::Type type, float alpha, std::array<uint8_t, 3> none_color) {
|
||||
switch (type) {
|
||||
case TimelineEntry::Type::Engaged:
|
||||
return ImGui::GetColorU32(color_rgb(0, 163, 108, alpha));
|
||||
case TimelineEntry::Type::AlertInfo:
|
||||
return ImGui::GetColorU32(color_rgb(255, 195, 0, alpha));
|
||||
case TimelineEntry::Type::AlertWarning:
|
||||
case TimelineEntry::Type::AlertCritical:
|
||||
return ImGui::GetColorU32(color_rgb(199, 0, 57, alpha));
|
||||
case TimelineEntry::Type::None:
|
||||
default:
|
||||
return ImGui::GetColorU32(color_rgb(none_color, alpha));
|
||||
}
|
||||
}
|
||||
|
||||
const char *timeline_entry_label(TimelineEntry::Type type) {
|
||||
static constexpr const char *kLabels[] = {
|
||||
"disengaged",
|
||||
"engaged",
|
||||
"alert info",
|
||||
"alert warning",
|
||||
"alert critical",
|
||||
};
|
||||
const size_t index = static_cast<size_t>(type);
|
||||
return index < std::size(kLabels) ? kLabels[index] : kLabels[0];
|
||||
}
|
||||
|
||||
TimelineEntry::Type timeline_type_at_time(const std::vector<TimelineEntry> &timeline, double time_value) {
|
||||
for (const TimelineEntry &entry : timeline) {
|
||||
if (time_value >= entry.start_time && time_value <= entry.end_time) {
|
||||
return entry.type;
|
||||
}
|
||||
}
|
||||
return TimelineEntry::Type::None;
|
||||
}
|
||||
|
||||
std::string normalize_stream_address(std::string address) {
|
||||
return is_local_stream_address(address) ? "127.0.0.1" : address;
|
||||
}
|
||||
|
||||
const char *stream_source_kind_label(StreamSourceKind kind) {
|
||||
static constexpr const char *kLabels[] = {
|
||||
"Local (MSGQ)",
|
||||
"Remote (ZMQ)",
|
||||
};
|
||||
const size_t index = static_cast<size_t>(kind);
|
||||
return index < std::size(kLabels) ? kLabels[index] : kLabels[0];
|
||||
}
|
||||
|
||||
std::string stream_source_target_label(const StreamSourceConfig &source) {
|
||||
switch (source.kind) {
|
||||
case StreamSourceKind::CerealRemote:
|
||||
return normalize_stream_address(source.address);
|
||||
case StreamSourceKind::CerealLocal:
|
||||
default:
|
||||
return "127.0.0.1";
|
||||
}
|
||||
}
|
||||
|
||||
bool env_flag_enabled(const char *name, bool default_value) {
|
||||
const char *raw = std::getenv(name);
|
||||
if (raw == nullptr || raw[0] == '\0') {
|
||||
return default_value;
|
||||
}
|
||||
const std::string value = lowercase_copy(util::strip(raw));
|
||||
return !(value == "0" || value == "false" || value == "no" || value == "off");
|
||||
}
|
||||
|
||||
bool app_begin_popup(const char *str_id, ImGuiWindowFlags flags) {
|
||||
return ImGui::BeginPopup(str_id, flags | ImGuiWindowFlags_NoMove);
|
||||
}
|
||||
|
||||
bool app_begin_popup_modal(const char *name, bool *p_open, ImGuiWindowFlags flags) {
|
||||
return ImGui::BeginPopupModal(name, p_open, flags | ImGuiWindowFlags_NoMove);
|
||||
}
|
||||
|
||||
void open_external_url(std::string_view url) {
|
||||
#ifdef __APPLE__
|
||||
const std::string command = "open " + shell_quote(url) + " &";
|
||||
#else
|
||||
const std::string command = "xdg-open " + shell_quote(url) + " >/dev/null 2>&1 &";
|
||||
#endif
|
||||
// IQ.Pilot patch: iqpilot's common/util.h has no `check_system`. Inline an
|
||||
// equivalent — log on non-zero exit, otherwise behave like std::system.
|
||||
const int ret = std::system(command.c_str());
|
||||
if (ret != 0) {
|
||||
std::cerr << "open_external_url: command failed (exit " << ret << "): " << command << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
std::string route_useradmin_url(const RouteIdentifier &route_id) {
|
||||
return route_id.empty() ? std::string()
|
||||
: "https://useradmin.comma.ai/?onebox=" + route_id.dongle_id + "%7C" + route_id.log_id;
|
||||
}
|
||||
|
||||
std::string route_connect_url(const RouteIdentifier &route_id) {
|
||||
return route_id.empty() ? std::string()
|
||||
: "https://connect.comma.ai/" + route_id.canonical();
|
||||
}
|
||||
|
||||
std::string route_google_maps_url(const GpsTrace &trace) {
|
||||
if (trace.points.size() < 2) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const std::string prefix = "https://www.google.com/maps/dir/?api=1&travelmode=driving&origin="
|
||||
+ format_coord(trace.points.front()) + "&destination=" + format_coord(trace.points.back());
|
||||
for (size_t n = std::min<size_t>(9, trace.points.size() > 2 ? trace.points.size() - 2 : 0); ; --n) {
|
||||
std::string url = prefix;
|
||||
if (n > 0) {
|
||||
url += "&waypoints=";
|
||||
for (size_t i = 0; i < n; ++i) {
|
||||
if (i) url += "%7C";
|
||||
url += format_coord(trace.points[1 + ((trace.points.size() - 2) * (i + 1)) / (n + 1)]);
|
||||
}
|
||||
}
|
||||
if (url.size() <= 1900 || n == 0) return url;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user