created
This commit is contained in:
133
README.md
133
README.md
@@ -1,2 +1,135 @@
|
||||
# odomety
|
||||
|
||||
Thư viện C++ ước lượng odometry cho robot **differential drive** (2 bánh chủ động).
|
||||
|
||||
Từ vận tốc góc bánh xe, **encoder ticks**, hoặc lệnh `v`/`ω`, thư viện tích phân pose 2D `(x, y, θ)` và vận tốc `(v, ω)` theo thời gian.
|
||||
|
||||
## Tính năng
|
||||
|
||||
- Cập nhật từ vận tốc góc bánh trái/phải `[rad/s]`
|
||||
- Cập nhật từ cumulative encoder ticks (`Encoder_Measurement`-style)
|
||||
- Cập nhật trực tiếp từ lệnh tuyến tính/góc `[m/s]`, `[rad/s]`
|
||||
- Tích phân exact (và Runge–Kutta bậc 2 khi gần đi thẳng)
|
||||
- Làm mượt vận tốc bằng rolling mean (Boost Accumulators)
|
||||
- Demo và unit test kèm theo
|
||||
|
||||
## Yêu cầu
|
||||
|
||||
- CMake ≥ 3.14
|
||||
- C++17
|
||||
- Boost (header: Accumulators, Function)
|
||||
|
||||
## Cấu trúc
|
||||
|
||||
```
|
||||
odomety/
|
||||
├── include/odometry/odom_differential.h
|
||||
├── src/odom_differential.cpp
|
||||
├── src/main.cpp # demo
|
||||
├── test/odom_differential_test.cpp
|
||||
└── CMakeLists.txt
|
||||
```
|
||||
|
||||
## Build
|
||||
|
||||
```bash
|
||||
cd odomety
|
||||
cmake -S . -B build
|
||||
cmake --build build
|
||||
```
|
||||
|
||||
Chạy demo:
|
||||
|
||||
```bash
|
||||
./build/odomety_demo
|
||||
```
|
||||
|
||||
Chạy test:
|
||||
|
||||
```bash
|
||||
cd build && ctest --output-on-failure
|
||||
# hoặc
|
||||
./build/odomety_test
|
||||
```
|
||||
|
||||
## Cài đặt (tùy chọn)
|
||||
|
||||
```bash
|
||||
sudo cmake --install build --prefix /path/to/install
|
||||
```
|
||||
|
||||
Trong project khác:
|
||||
|
||||
```cmake
|
||||
find_package(odomety REQUIRED)
|
||||
target_link_libraries(your_target PRIVATE odomety::odom_differential)
|
||||
```
|
||||
|
||||
## Cách dùng
|
||||
|
||||
### Từ vận tốc bánh
|
||||
|
||||
```cpp
|
||||
#include <odometry/odom_differential.h>
|
||||
|
||||
differential::Odometry odom(/*velocity_rolling_window_size=*/10);
|
||||
|
||||
odom.setWheelParams(
|
||||
/*wheel_separation=*/0.5, // [m]
|
||||
/*left_wheel_radius=*/0.09, // [m]
|
||||
/*right_wheel_radius=*/0.09 // [m]
|
||||
);
|
||||
|
||||
odom.init(/*time_sec=*/t0);
|
||||
odom.updateWheel(left_omega, right_omega, t); // [rad/s]
|
||||
```
|
||||
|
||||
### Từ encoder ticks (khuyến nghị khi có đếm xung)
|
||||
|
||||
```cpp
|
||||
odom.setWheelParams(0.5, 0.09, 0.09);
|
||||
odom.setEncoderParams(/*ticks_per_revolution=*/4096); // phía bánh, sau gearbox
|
||||
odom.init(t0);
|
||||
|
||||
// Cumulative tick counts (unwrap overflow về int64 monotonic trước khi gọi)
|
||||
odom.updateTicks(left_ticks, right_ticks, t); // lần đầu chỉ seed, trả về false
|
||||
|
||||
double x = odom.getX();
|
||||
double y = odom.getY();
|
||||
double yaw = odom.getHeading();
|
||||
double v = odom.getLinear();
|
||||
double w = odom.getAngular();
|
||||
```
|
||||
|
||||
Công thức nội bộ mỗi bước:
|
||||
|
||||
- `Δs_L/R = 2π · r_L/R · Δn_L/R / N_L/R`
|
||||
- `Δs = (Δs_L + Δs_R) / 2`
|
||||
- `Δθ = (Δs_R − Δs_L) / b`
|
||||
|
||||
### Từ lệnh vận tốc (open-loop)
|
||||
|
||||
```cpp
|
||||
odom.updateOdom(linear_mps, angular_rps, t);
|
||||
```
|
||||
|
||||
## API chính
|
||||
|
||||
| Hàm | Mô tả |
|
||||
|---|---|
|
||||
| `init(time)` | Reset pose/vận tốc/tick seed và gắn timestamp |
|
||||
| `setWheelParams(sep, r_l, r_r)` | Khoảng cách bánh và bán kính |
|
||||
| `setEncoderParams(N)` / `setEncoderParams(N_l, N_r)` | CPR phía bánh |
|
||||
| `updateWheel(ω_l, ω_r, time)` | Cập nhật từ vận tốc góc bánh |
|
||||
| `updateTicks(n_l, n_r, time)` | Cập nhật từ cumulative encoder ticks |
|
||||
| `updateOdom(v, ω, time)` | Cập nhật từ lệnh vận tốc |
|
||||
| `getX/Y/Heading/Linear/Angular()` | Đọc trạng thái hiện tại |
|
||||
|
||||
## Ghi chú
|
||||
|
||||
- `updateWheel` / `updateTicks` trả về `false` nếu `dt < 0.0001` s.
|
||||
- `updateTicks`: lần gọi đầu sau `init` chỉ lưu tick trước đó (seed), không tích phân.
|
||||
- `updateTicks` trả về `false` nếu chưa gọi `setEncoderParams` (CPR ≤ 0).
|
||||
- Tick phải là đếm **phía bánh** (sau gearbox). Overflow counter phần cứng cần unwrap về `int64` monotonic.
|
||||
- Đơn vị thời gian là giây (epoch hoặc monotonic, miễn nhất quán).
|
||||
- Pose mặc định sau `init`: `(0, 0, 0)`.
|
||||
|
||||
Reference in New Issue
Block a user