Skip to content

Commit fd971d5

Browse files
authored
Merge pull request #157 from cogip/134-pami-use-new-lidar-instead-of-tof-to-detect-obstacles
PAMI: use new Lidar instead of ToF to detect obstacles
2 parents 399b6be + 2faac38 commit fd971d5

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

78 files changed

+2879
-961
lines changed

.github/workflows/build-wheel.yml

Lines changed: 3 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -21,34 +21,10 @@ jobs:
2121
- name: Set up Docker Buildx
2222
uses: docker/setup-buildx-action@v3
2323

24-
- name: Cache Docker layers
25-
uses: actions/cache@v4
26-
with:
27-
path: /tmp/.buildx-cache
28-
key: ${{ runner.os }}-buildx-${{ github.sha }}
29-
restore-keys: |
30-
${{ runner.os }}-buildx-
31-
32-
- name: Build docker image with layer caching
33-
uses: docker/build-push-action@v4
34-
with:
35-
context: .
36-
target: uv_base
37-
platforms: linux/arm64
38-
load: true
39-
cache-from: type=local,src=/tmp/.buildx-cache
40-
cache-to: type=local,dest=/tmp/.buildx-cache-new,mode=max
41-
42-
- # Temp fix
43-
# https://github.com/docker/build-push-action/issues/252
44-
# https://github.com/moby/buildkit/issues/1896
45-
name: Move cache
46-
run: |
47-
rm -rf /tmp/.buildx-cache
48-
mv /tmp/.buildx-cache-new /tmp/.buildx-cache
49-
5024
- name: Build wheel
51-
run: docker compose up build_wheel
25+
run: |
26+
docker compose pull build_wheel
27+
docker compose up build_wheel
5228
5329
- name: Check if wheel exists
5430
run: |

cogip/cpp/CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
list(
2+
APPEND
3+
CMAKE_INSTALL_RPATH
4+
"$ORIGIN/../libraries"
5+
"$ORIGIN/../drivers"
6+
)
7+
18
add_subdirectory(examples)
29
add_subdirectory(drivers)
310
add_subdirectory(libraries)

cogip/cpp/drivers/lidar_ld19/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ target_include_directories(
1717
PUBLIC
1818
${CMAKE_CURRENT_SOURCE_DIR}/include
1919
)
20-
target_link_libraries(lidar_ld19 PRIVATE ${LibSerial_LIBRARIES})
20+
target_link_libraries(lidar_ld19 PRIVATE ${LibSerial_LIBRARIES} models shared_memory)
2121
set_target_properties(lidar_ld19 PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/..)
2222

2323
# Install the library.
@@ -35,6 +35,7 @@ nanobind_add_stub(
3535
PYTHON_PATH ${CMAKE_BINARY_DIR}
3636
DEPENDS lidar_ld19
3737
VERBOSE
38+
INSTALL_TIME
3839
)
3940

4041
# Copy stub files into the source directory.

cogip/cpp/drivers/lidar_ld19/binding.cpp

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,14 @@
88
#include "lidar_ld19/ldlidar_driver.h"
99

1010
namespace nb = nanobind;
11+
using namespace nb::literals;
1112

1213
namespace ldlidar {
1314

1415
NB_MODULE(lidar_ld19, m) {
16+
auto models_module = nb::module_::import_("cogip.cpp.libraries.models");
17+
auto shared_memory_module = nb::module_::import_("cogip.cpp.libraries.shared_memory");
18+
1519
nb::enum_<LibSerial::BaudRate>(m, "BaudRate")
1620
.value("BAUD_230400", LibSerial::BaudRate::BAUD_230400);
1721

@@ -24,10 +28,9 @@ NB_MODULE(lidar_ld19, m) {
2428

2529
nb::class_<LDLidarDriver>(m, "LDLidarDriver")
2630
.def(nb::init<>(), "Constructor that internally manages memory")
27-
.def(
28-
nb::init<nb::ndarray<uint16_t, nb::numpy, nb::shape<ldlidar::NUM_ANGLES, 2>>>(),
29-
"Constructor with external NumPy array",
30-
nb::arg("external_lidar_points")
31+
.def(nb::init<nb::ndarray<float, nb::numpy, nb::shape<MAX_DATA_COUNT, 3>>>(),
32+
"Constructor accepting nanobind::ndarray",
33+
"external_lidar_data"_a
3134
)
3235
.def("connect", &LDLidarDriver::connect)
3336
.def("disconnect", &LDLidarDriver::disconnect)
@@ -45,12 +48,18 @@ NB_MODULE(lidar_ld19, m) {
4548
)
4649
.def(
4750
"get_lidar_data",
48-
[](const LDLidarDriver &self) -> nb::ndarray<uint16_t, nb::numpy, nb::shape<NUM_ANGLES, 2>> {
51+
[](const LDLidarDriver &self) -> nb::ndarray<float, nb::numpy, nb::shape<MAX_DATA_COUNT, 3>> {
4952
const auto &points = self.getLidarData();
50-
return nb::ndarray<uint16_t, nb::numpy, nb::shape<NUM_ANGLES, 2>>((void *)points);
53+
return nb::ndarray<float, nb::numpy, nb::shape<MAX_DATA_COUNT, 3>>((void *)points);
5154
},
5255
nb::rv_policy::reference_internal
53-
);
56+
)
57+
.def("set_data_write_lock", &LDLidarDriver::setDataWriteLock, "Set the data write lock", "lock"_a)
58+
.def("set_min_intensity", &LDLidarDriver::setMinIntensity, "Set the minimum intensity value to validate data", "min_intensity"_a)
59+
.def("set_min_distance", &LDLidarDriver::setMinDistance, "Set the minimum distance to validate data", "min_distance"_a)
60+
.def("set_max_distance", &LDLidarDriver::setMaxDistance, "Set the maximum distance to validate data", "max_distance"_a)
61+
.def("set_invalid_angle_range", &LDLidarDriver::setInvalidAngleRange, "Set the invalid angle range", "min_angle"_a, "max_angle"_a)
62+
;
5463
}
5564

5665
} // namespace ldlidar

cogip/cpp/drivers/lidar_ld19/include/lidar_ld19/ldlidar_driver.h

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#include "lidar_ld19/ldlidar_datatype.h"
44
#include "lidar_ld19/ldlidar_protocol.h"
5+
#include "shared_memory/WritePriorityLock.hpp"
56

67
#include <libserial/SerialPort.h>
78

@@ -19,17 +20,17 @@ namespace nb = nanobind;
1920
namespace ldlidar {
2021

2122
constexpr size_t MAX_ACK_BUF_LEN = 512;
22-
constexpr size_t NUM_ANGLES = 360;
23+
constexpr std::size_t MAX_DATA_COUNT = 1024;
2324

2425
uint64_t getSystemTimeStamp();
2526

2627
class LDLidarDriver {
2728
public:
2829
/// Constructor with optional external memory pointer
29-
explicit LDLidarDriver(uint16_t (*external_lidar_data)[2] = nullptr);
30+
explicit LDLidarDriver(float (*external_lidar_data)[3] = nullptr);
3031

3132
/// Constructor accepting a nanobind::ndarray
32-
explicit LDLidarDriver(nb::ndarray<uint16_t, nb::numpy, nb::shape<NUM_ANGLES, 2>> external_lidar_data);
33+
explicit LDLidarDriver(nb::ndarray<float, nb::numpy, nb::shape<MAX_DATA_COUNT, 3>> external_lidar_data);
3334

3435
~LDLidarDriver();
3536

@@ -82,8 +83,17 @@ class LDLidarDriver {
8283
/// Function executed after reading data on serial port.
8384
void commReadCallback(const char *byte, size_t len);
8485

86+
/// Set the minimum intensity value to validate data.
87+
void setMinIntensity(uint8_t min_intensity) { min_intensity_ = min_intensity; }
88+
89+
/// Set the minimum distance to validate data.
90+
void setMinDistance(uint16_t min_distance) { min_distance_ = min_distance; }
91+
92+
/// Set the maximum distance to validate data.
93+
void setMaxDistance(uint16_t max_distance) { max_distance_ = max_distance; }
94+
8595
/// Get pointer to internal lidar points
86-
const uint16_t (&getLidarData() const)[2] { return *lidar_data_; }
96+
const float (&getLidarData() const)[3] { return *lidar_data_; }
8797

8898
/// Get Lidar spin speed (Hz)
8999
double getSpeed() const { return (speed_ / 360.0); };
@@ -103,6 +113,17 @@ class LDLidarDriver {
103113
tmp_lidar_scan_data_vec_.clear();
104114
}
105115

116+
/// Set the data write lock.
117+
void setDataWriteLock(cogip::shared_memory::WritePriorityLock &lock) {
118+
data_write_lock_ = &lock;
119+
}
120+
121+
/// Set invalid angle range
122+
void setInvalidAngleRange(uint16_t min_angle, uint16_t max_angle) {
123+
min_angle_ = min_angle;
124+
max_angle_ = max_angle;
125+
}
126+
106127
protected:
107128
bool is_start_flag_;
108129
bool is_connect_flag_;
@@ -117,15 +138,20 @@ class LDLidarDriver {
117138
LidarStatus lidar_status_;
118139
uint8_t lidar_error_code_;
119140
bool is_frame_ready_;
120-
bool is_noise_filter_;
141+
bool external_data_; ///< Flag to indicate if memory is externally managed
142+
float (*lidar_data_)[3]; ///< Pointer to lidar data memory
143+
cogip::shared_memory::WritePriorityLock *data_write_lock_;
144+
uint8_t min_intensity_;
121145
uint16_t timestamp_;
146+
uint16_t min_distance_;
147+
uint16_t max_distance_;
148+
uint16_t min_angle_;
149+
uint16_t max_angle_;
122150
double speed_;
123151
bool is_poweron_comm_normal_;
124152
uint64_t last_pkg_timestamp_;
125153
LdLidarProtocol *protocol_handle_;
126154
Points2D tmp_lidar_scan_data_vec_;
127-
uint16_t (*lidar_data_)[2]; ///< Pointer to lidar data memory
128-
bool external_data_; ///< Flag to indicate if memory is externally managed
129155
std::mutex mutex_lock1_;
130156
std::mutex mutex_lock2_;
131157

cogip/cpp/drivers/lidar_ld19/ldlidar_driver.cpp

Lines changed: 47 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,7 @@
1111

1212
namespace ldlidar {
1313

14-
constexpr uint16_t max_distance = 3000;
15-
constexpr uint8_t min_intensity = 150;
14+
constexpr size_t FILTERED_DATA_COUNT = 360;
1615

1716
uint64_t getSystemTimeStamp() {
1817
std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds> tp =
@@ -23,20 +22,20 @@ uint64_t getSystemTimeStamp() {
2322

2423
bool LDLidarDriver::is_ok_ = false;
2524

26-
LDLidarDriver::LDLidarDriver(uint16_t (*external_lidar_data)[2]):
25+
LDLidarDriver::LDLidarDriver(float (*external_lidar_data)[3]):
2726
lidar_data_(external_lidar_data),
2827
external_data_(external_lidar_data != nullptr)
2928
{
3029
if (!external_data_) {
3130
// Allocate memory if external pointer is not provided
32-
lidar_data_ = new uint16_t[NUM_ANGLES][2]();
31+
lidar_data_ = new float[MAX_DATA_COUNT][3]();
3332
}
3433

3534
commonInit();
3635
}
3736

38-
LDLidarDriver::LDLidarDriver(nb::ndarray<uint16_t, nb::numpy, nb::shape<NUM_ANGLES, 2>> external_lidar_points):
39-
lidar_data_(reinterpret_cast<uint16_t(*)[2]>(external_lidar_points.data())),
37+
LDLidarDriver::LDLidarDriver(nb::ndarray<float, nb::numpy, nb::shape<MAX_DATA_COUNT, 3>> external_lidar_raw_points):
38+
lidar_data_(reinterpret_cast<float(*)[3]>(external_lidar_raw_points.data())),
4039
external_data_(true)
4140
{
4241
if (!lidar_data_) {
@@ -53,6 +52,12 @@ void LDLidarDriver::commonInit() {
5352
lidar_status_ = LidarStatus::NORMAL;
5453
lidar_error_code_ = LIDAR_NO_ERROR;
5554
is_frame_ready_ = false;
55+
data_write_lock_ = nullptr;
56+
min_intensity_ = 0;
57+
min_distance_ = 0;
58+
max_distance_ = std::numeric_limits<uint16_t>::max();
59+
min_angle_ = 0;
60+
max_angle_ = 360;
5661
timestamp_ = 0;
5762
speed_ = 0;
5863
is_poweron_comm_normal_ = false;
@@ -340,34 +345,49 @@ void LDLidarDriver::setFrameReady() {
340345

341346
void LDLidarDriver::setLaserScanData(Points2D &src) {
342347
std::lock_guard<std::mutex> lg(mutex_lock2_);
343-
std::array<uint16_t, NUM_ANGLES> result_distances;
344-
std::array<uint8_t, NUM_ANGLES> result_intensities;
345-
std::array<std::vector<uint16_t>, NUM_ANGLES> tmp_distances;
346-
std::array<std::vector<uint8_t>, NUM_ANGLES> tmp_intensities;
348+
std::array<std::vector<uint16_t>, FILTERED_DATA_COUNT> tmp_distances;
349+
std::array<std::vector<uint8_t>, FILTERED_DATA_COUNT> tmp_intensities;
347350

348351
// Build a list of points for each integer degree
352+
std::size_t count = 0;
353+
354+
// Compute mean of points list for each degree.
355+
if (data_write_lock_ != nullptr) {
356+
data_write_lock_->startWriting();
357+
}
358+
349359
for (const auto &point: src) {
350-
if (point.intensity < min_intensity) {
360+
if (point.intensity < min_intensity_) {
351361
continue;
352362
}
353-
size_t angle = (static_cast<size_t>(point.angle) + NUM_ANGLES) % NUM_ANGLES;
354-
tmp_distances[angle].push_back(point.distance);
355-
tmp_intensities[angle].push_back(point.intensity);
356-
}
357-
358-
// Compute mean of points list for each degree.
359-
for (size_t angle = 0; angle < NUM_ANGLES; angle++) {
360-
const auto &distances = tmp_distances[angle];
361-
const auto &intensities = tmp_intensities[angle];
362-
size_t size = distances.size();
363-
if (size > 0) {
364-
lidar_data_[angle][0] = std::accumulate(distances.begin(), distances.end(), 0) / size;
365-
lidar_data_[angle][1] = std::accumulate(intensities.begin(), intensities.end(), 0) / size;
363+
if (point.distance < min_distance_) {
364+
continue;
365+
}
366+
if (point.distance > max_distance_) {
367+
continue;
366368
}
367-
else {
368-
lidar_data_[angle][0] = max_distance; // Mark as invalid
369-
lidar_data_[angle][1] = 0; // Mark as invalid
369+
370+
double angle = 360 - point.angle; // Lidar angle is inverted
371+
372+
// Skip excluded angles
373+
if (angle > min_angle_ && angle < max_angle_) {
374+
continue;
370375
}
376+
377+
lidar_data_[count][0] = angle;
378+
lidar_data_[count][1] = point.distance;
379+
lidar_data_[count][2] = point.intensity;
380+
count++;
381+
}
382+
383+
// Mark as end of data
384+
lidar_data_[count][0] = -1.0;
385+
lidar_data_[count][1] = -1.0;
386+
lidar_data_[count][2] = -1.0;
387+
388+
if (data_write_lock_ != nullptr) {
389+
data_write_lock_->finishWriting();
390+
data_write_lock_->postUpdate();
371391
}
372392
}
373393

cogip/cpp/examples/nanobind_example/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ nanobind_add_stub(
2727
PYTHON_PATH ${CMAKE_BINARY_DIR}
2828
DEPENDS nanobind_example
2929
VERBOSE
30+
INSTALL_TIME
3031
)
3132

3233
# Copy stub files into the source directory.

cogip/cpp/libraries/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ add_subdirectory(models)
22
add_subdirectory(obstacles)
33
add_subdirectory(shared_memory)
44
add_subdirectory(avoidance)
5+
add_subdirectory(utils)

cogip/cpp/libraries/avoidance/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ nanobind_add_stub(
4646
PYTHON_PATH ${CMAKE_BINARY_DIR}
4747
DEPENDS avoidance models_stub obstacles_stub
4848
VERBOSE
49+
INSTALL_TIME
4950
)
5051

5152
# Copy stub files into the source directory.

cogip/cpp/libraries/models/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
add_library(
44
models_cpp
55
SHARED
6+
Circle.cpp
7+
CircleList.cpp
68
Coords.cpp
79
CoordsList.cpp
810
Polar.cpp
@@ -41,6 +43,7 @@ nanobind_add_stub(
4143
PYTHON_PATH ${CMAKE_BINARY_DIR}
4244
DEPENDS models
4345
VERBOSE
46+
INSTALL_TIME
4447
)
4548

4649
# Copy stub files into the source directory.

0 commit comments

Comments
 (0)