// test_dual.cpp — test 2 Olei lidars (front + rear) concurrently, per appsettings.json // Olei-front: scan_1, DeviceIp 192.168.100.11, LocalIp 192.168.100.100, DevicePort 2368 // Olei-rear : scan_2, DeviceIp 192.168.100.12, LocalIp 192.168.100.100, DevicePort 2369 #include "olei_lidar.hpp" #include #include static void run_lidar(const char* tag, const olei::ModelConfig& cfg, const std::string& local_ip, uint16_t port, int n_scans) { olei::Driver drv(cfg, local_ip, port); if (!drv.open()) { fprintf(stderr, "[%s] Khong mo duoc socket tren %s:%u (interface khong ton tai?)\n", tag, local_ip.c_str(), port); return; } printf("[%s] Da bind %s:%u, dang doi scan...\n", tag, local_ip.c_str(), port); for (int i = 0; i < n_scans; ++i) { olei::Scan scan; if (!drv.recv_scan(scan, 2000)) { fprintf(stderr, "[%s] Timeout/loi nhan packet (scan #%d)\n", tag, i); continue; } printf("[%s] Scan #%d: %zu diem, ts=%u ms, err=0x%02X, model=%s\n", tag, i, scan.points.size(), scan.timestamp_ms, scan.error_status, drv.detected_model()); for (size_t j = 0; j < 3 && j < scan.points.size(); ++j) { const auto& p = scan.points[j]; printf(" [%zu] angle=%.2f dist=%.3fm intensity=%u\n", j, p.angle_deg, p.distance_m, p.intensity); } } drv.close(); } int main() { // Both front and rear are Family B in practice — front's real header // string is "OLELR-1BS2", rear's is "OLELR-1BS5" (verified via live UDP // sniff), NOT the VB (Family A) model the config name suggested. With // MODEL_AUTO, the driver reads the real model name from the header and // narrows the FOV when it matches a known entry in kModelTable // (olei_lidar.cpp); "1BS5" matches (→ full 360°), but "1BS2" doesn't, so // front currently stays at the unfiltered 360° default. Call // drv.detected_model() to see which name was actually read. std::thread t_front(run_lidar, "front/scan_1", olei::MODEL_AUTO, "192.168.100.100", 2368, 5); std::thread t_rear(run_lidar, "rear/scan_2", olei::MODEL_AUTO, "192.168.100.100", 2369, 5); t_front.join(); t_rear.join(); return 0; }