update ErrorCode, status, lifecycle
This commit is contained in:
71
README.md
71
README.md
@@ -41,10 +41,17 @@ target_link_libraries(my_app PRIVATE lidarlib::lidarlib)
|
||||
|
||||
lidarlib::LidarConfig c{"front", "192.168.1.10", 2368, "AUTO", false, "OLEI"};
|
||||
std::unique_ptr<lidarlib::Lidar> lidar = lidarlib::make_lidar(c);
|
||||
lidar->open();
|
||||
|
||||
lidarlib::ErrorCode err = lidar->open();
|
||||
if (err != lidarlib::ErrorCode::Ok) {
|
||||
fprintf(stderr, "open that bai: %s\n", lidarlib::to_string(err));
|
||||
return 1;
|
||||
}
|
||||
|
||||
lidarlib::ScanResult r;
|
||||
lidar->recv_scan(r, 1000);
|
||||
if (!lidar->recv_scan(r, 1000)) {
|
||||
// Timeout / DeviceDisconnected / NotOpen — xem lidar->last_error()
|
||||
}
|
||||
// r.scan : LaserScan — format sensor_msgs/LaserScan của ROS, chung mọi lidar
|
||||
// r.info : ExtraInfo — thông tin thêm tuỳ family/model
|
||||
printf("%zu diem, model=%s\n", r.scan.ranges.size(), r.info.detected_model.c_str());
|
||||
@@ -61,6 +68,33 @@ lidarlib::NanoScanDriver nano(lidarlib::MODEL_SICK_NANOSCAN3, "0.0.0.0", 6060);
|
||||
Ngoài `recv_scan()` blocking còn có callback: `set_scan_callback()` +
|
||||
`spin_once()` trong vòng lặp riêng.
|
||||
|
||||
### Error handling & lifecycle
|
||||
|
||||
`open()` trả về `lidarlib::ErrorCode` (header `lidarlib/error.hpp`,
|
||||
`to_string()` để log). Các code chính:
|
||||
|
||||
| ErrorCode | Khi nào |
|
||||
|---|---|
|
||||
| `Ok` | Thành công |
|
||||
| `AlreadyOpen` | Gọi `open()` khi đang mở — kết nối cũ giữ nguyên |
|
||||
| `NotOpen` | Gọi `recv_scan()`/`spin_once()` khi chưa `open()` |
|
||||
| `InvalidAddress` | Chuỗi IP không hợp lệ |
|
||||
| `PortInUse` | Port local đã bị chiếm (bind `EADDRINUSE`/`EACCES`) |
|
||||
| `BindFailed` / `SocketError` | Lỗi bind khác / không tạo được socket |
|
||||
| `ConnectionRefused` / `ConnectionFailed` / `Timeout` | TCP connect (SICK TiM) bị từ chối / không tới được / quá 2s |
|
||||
| `HandshakeFailed` | TCP nối được nhưng gửi `sEN LMDscandata 1` thất bại |
|
||||
| `DeviceDisconnected` | Thiết bị đóng kết nối / lỗi recv giữa chừng |
|
||||
|
||||
Trạng thái instance:
|
||||
|
||||
- `is_open()` — socket đang mở hay không.
|
||||
- `last_error()` — kết quả của lần `open()`/`recv_scan()`/`spin_once()` gần
|
||||
nhất (`recv_scan()` trả `false` thì gọi hàm này để biết `Timeout` hay
|
||||
`DeviceDisconnected`).
|
||||
- Lifecycle chịu lỗi mọi thứ tự gọi: `close()` trước `open()` hoặc `close()`
|
||||
hai lần là no-op; `open()` hai lần trả `AlreadyOpen` và không đụng kết nối
|
||||
đang chạy; sau `close()` có thể `open()` lại (state scan dở được reset).
|
||||
|
||||
## Cấu hình (config.json)
|
||||
|
||||
`lidar_app` là app mẫu headless: đọc `config.json`, mở từng lidar bằng
|
||||
@@ -150,6 +184,7 @@ parse datagram; **đích UDP phải cấu hình sẵn trong SICK Safety Designer
|
||||
|
||||
| File | Vai trò |
|
||||
|---|---|
|
||||
| `include/lidarlib/error.hpp` | `enum class ErrorCode` + `to_string()` |
|
||||
| `include/lidarlib/lidar.hpp` | Data model, interface `Lidar`, driver OLEI, các `MODEL_*` OLEI |
|
||||
| `include/lidarlib/sick_lidar.hpp` | `SickDriver`, `NanoScanDriver`, các `MODEL_SICK_*` |
|
||||
| `include/lidarlib/config.hpp` | `LidarConfig`, load/save JSON, `make_lidar()` |
|
||||
@@ -160,7 +195,35 @@ parse datagram; **đích UDP phải cấu hình sẵn trong SICK Safety Designer
|
||||
|
||||
## Ghi chú
|
||||
|
||||
- Nếu port UDP đã bị app khác giữ (không bật `SO_REUSEPORT`), `open()` sẽ thất
|
||||
bại. Kiểm tra: `ss -lunp | grep 2368`.
|
||||
- Nếu port UDP đã bị app khác giữ (không bật `SO_REUSEPORT`), `open()` trả
|
||||
`ErrorCode::PortInUse`. Kiểm tra: `ss -lunp | grep 2368`.
|
||||
- `inverted` đã verify bằng sniff sống: `false` góc tăng dần, `true` góc giảm
|
||||
dần cùng bước.
|
||||
|
||||
## Changelog
|
||||
|
||||
### 2026-07-06 — Error handling & lifecycle API
|
||||
|
||||
- **Header mới `lidarlib/error.hpp`**: `enum class ErrorCode` — `Ok`,
|
||||
`AlreadyOpen`, `NotOpen`, `SocketError`, `InvalidAddress`, `PortInUse`,
|
||||
`BindFailed`, `ConnectionRefused`, `ConnectionFailed`, `HandshakeFailed`,
|
||||
`Timeout`, `DeviceDisconnected` — kèm `to_string()` để log.
|
||||
- **`open()` đổi chữ ký `bool` → `ErrorCode`** trên cả 3 driver (`Driver`,
|
||||
`SickDriver`, `NanoScanDriver`). Lỗi phân loại từ `errno` thật: bind
|
||||
`EADDRINUSE` → `PortInUse`, connect TCP bị từ chối → `ConnectionRefused`,
|
||||
quá 2s → `Timeout`, gửi lệnh start-stream fail → `HandshakeFailed`,
|
||||
IP sai format → `InvalidAddress`.
|
||||
- **API trạng thái mới trên interface `Lidar`**:
|
||||
- `is_open()` — socket đang mở hay không (cả 3 driver implement);
|
||||
- `last_error()` — kết quả lần `open()`/`recv_scan()`/`spin_once()` gần
|
||||
nhất; `recv_scan()` trả `false` thì gọi hàm này để biết `Timeout` hay
|
||||
`DeviceDisconnected`.
|
||||
- **Lifecycle chịu lỗi mọi thứ tự gọi**: `close()` trước `open()` hoặc gọi
|
||||
hai lần là no-op; `open()` khi đang mở trả `AlreadyOpen` và không đụng kết
|
||||
nối đang chạy; `recv_scan()`/`spin_once()` khi chưa mở trả `false` +
|
||||
`NotOpen`; sau `close()` có thể `open()` lại (state scan dở được reset).
|
||||
- **`NanoScanDriver` bỏ `SO_REUSEADDR`**: với UDP không có tác dụng (không có
|
||||
TIME_WAIT) mà còn che mất lỗi trùng port — giờ `PortInUse` báo được thật.
|
||||
- ⚠️ **Breaking change**: code cũ viết `if (!lidar->open())` bị đảo ngược
|
||||
logic vì `ErrorCode::Ok == 0` — phải đổi thành
|
||||
`if (lidar->open() != lidarlib::ErrorCode::Ok)`.
|
||||
|
||||
Reference in New Issue
Block a user