19 #ifndef _USE_MATH_DEFINES
20 #define _USE_MATH_DEFINES
25 #define DEG2RAD M_PI/180.0
31 using namespace rp::standalone::rplidar;
43 m_device_status = DEVICE_OK_STANBY;
49 if (this->parseConfiguration(config) ==
false)
55 bool br = config.check(
"GENERAL");
59 if (general_config.
check(
"serial_port") ==
false) {
yCError(
RP2_LIDAR) <<
"Missing serial_port param in GENERAL group";
return false; }
60 if (general_config.
check(
"serial_baudrate") ==
false) {
yCError(
RP2_LIDAR) <<
"Missing serial_baudrate param in GENERAL group";
return false; }
61 if (general_config.
check(
"sample_buffer_life") ==
false) {
yCError(
RP2_LIDAR) <<
"Missing sample_buffer_life param in GENERAL group";
return false; }
63 baudrate = general_config.
find(
"serial_baudrate").
asInt32();
64 m_serialPort = general_config.
find(
"serial_port").
asString();
65 m_buffer_life = general_config.
find(
"sample_buffer_life").
asInt32();
66 if (general_config.
check(
"motor_pwm"))
68 m_pwm_val = general_config.
find(
"motor_pwm").
asInt32();
70 if (general_config.
check(
"thread_period"))
72 double thread_period = general_config.
find(
"thread_period").
asInt32() / 1000.0;
73 this->setPeriod(thread_period);
82 m_drv = RPlidarDriver::CreateDriver(rp::standalone::rplidar::DRIVER_TYPE_SERIALPORT);
89 if (IS_FAIL(m_drv->connect(m_serialPort.c_str(), (_u32)baudrate)))
91 yCError(
RP2_LIDAR) <<
"Error, cannot bind to the specified serial port:", m_serialPort.c_str();
92 RPlidarDriver::DisposeDriver(m_drv);
96 m_info = deviceinfo();
97 yCInfo(
RP2_LIDAR,
"max_dist %f, min_dist %f", m_max_distance, m_min_distance);
99 bool m_inExpressMode=
false;
100 result = m_drv->checkExpressScanSupported(m_inExpressMode);
101 if (result == RESULT_OK && m_inExpressMode==
true)
110 result = m_drv->startMotor();
111 if (result != RESULT_OK)
120 if (m_pwm_val>0 && m_pwm_val<1023)
122 result = m_drv->setMotorPWM(m_pwm_val);
123 if (result != RESULT_OK)
132 yCError(
RP2_LIDAR) <<
"Invalid motor pwm request " << m_pwm_val <<
". It should be a value between 0 and 1023.";
141 bool forceScan =
false;
142 result = m_drv->startScan(forceScan,m_inExpressMode);
144 if (result != RESULT_OK)
152 yCInfo(
RP2_LIDAR,
"max_angle %f, min_angle %f", m_max_angle, m_min_angle);
155 PeriodicThread::start();
162 RPlidarDriver::DisposeDriver(m_drv);
163 PeriodicThread::stop();
170 std::lock_guard<std::mutex> guard(m_mutex);
171 m_min_distance = min;
172 m_max_distance = max;
178 std::lock_guard<std::mutex> guard(m_mutex);
186 std::lock_guard<std::mutex> guard(m_mutex);
193 std::lock_guard<std::mutex> guard(m_mutex);
205 #define _countof(_Array) (int)(sizeof(_Array) / sizeof (_Array[0]))
218 rplidar_response_measurement_node_t nodes[2048];
221 op_result = m_drv->grabScanData(nodes, count);
222 if (op_result != RESULT_OK)
225 handleError(op_result);
230 bool is4kmode =
false;
231 op_result = m_drv->getFrequency(m_inExpressMode, count, frequency, is4kmode);
232 if (op_result != RESULT_OK)
238 m_drv->ascendScanData(nodes, count);
240 if (op_result != RESULT_OK)
243 handleError(op_result);
247 if (m_buffer_life && life % m_buffer_life == 0)
249 for (
size_t i = 0; i < m_laser_data.size(); i++)
252 m_laser_data[i] = std::numeric_limits<double>::infinity();
260 for (
size_t i = 0; i < count; ++i)
263 double distance = nodes[i].distance_q2 / 4.0f / 1000.0;
264 double angle = (float)((nodes[i].angle_q6_checkbit >> RPLIDAR_RESP_MEASUREMENT_ANGLE_SHIFT) / 64.0f);
265 double quality = nodes[i].sync_quality >> RPLIDAR_RESP_MEASUREMENT_QUALITY_SHIFT;
266 angle = (360 - angle);
279 if (quality == 0 || distance == 0)
281 distance = std::numeric_limits<double>::infinity();
284 int elem = (int)(angle / m_resolution);
285 if (elem >= 0 && elem < (
int)m_laser_data.size())
287 m_laser_data[elem] = distance;
291 yCDebug(
RP2_LIDAR) <<
"RpLidar::run() invalid angle: elem" << elem <<
">" <<
"laser_data.size()" << m_laser_data.size();
309 void RpLidar2::handleError(u_result error)
313 case RESULT_FAIL_BIT:
316 case RESULT_ALREADY_DONE:
319 case RESULT_INVALID_DATA:
322 case RESULT_OPERATION_FAIL:
325 case RESULT_OPERATION_TIMEOUT:
328 case RESULT_OPERATION_STOP:
331 case RESULT_OPERATION_NOT_SUPPORT:
334 case RESULT_FORMAT_NOT_SUPPORT:
337 case RESULT_INSUFFICIENT_MEMORY:
343 std::string RpLidar2::deviceinfo()
348 rplidar_response_device_info_t info;
349 std::string serialNumber;
351 result = m_drv->getDeviceInfo(info);
352 if (result != RESULT_OK)
358 for (
unsigned char i : info.serialnum)
363 return "Firmware Version: " +
std::to_string(info.firmware_version) +
366 "\nSerial Number:" + serialNumber;
rpLidar2: The device driver for the RP2 lidar
bool setScanRate(double rate) override
set the scan rate (scans per seconds)
bool setScanLimits(double min, double max) override
set the scan angular range.
bool close() override
Close the DeviceDriver.
bool threadInit() override
Initialization method.
bool acquireDataFromHW() override final
This method should be implemented by the user, and contain the logic to grab data from the hardware.
bool setDistanceRange(double min, double max) override
set the device detection range.
bool setHorizontalResolution(double step) override
get the angular step between two measurments (if available)
void threadRelease() override
Release method.
void run() override
Loop function.
A base class for nested structures that can be searched.
virtual Value & find(const std::string &key) const =0
Gets a value corresponding to a given keyword.
virtual bool check(const std::string &key) const =0
Check if there exists a property of the given name.
virtual Bottle & findGroup(const std::string &key) const =0
Gets a list corresponding to a given keyword.
virtual std::int32_t asInt32() const
Get 32-bit integer value.
virtual std::string asString() const
Get string value.
#define yCInfo(component,...)
#define yCError(component,...)
#define yCWarning(component,...)
#define yCDebug(component,...)
#define YARP_LOG_COMPONENT(name,...)
std::string to_string(IntegerType x)
The main, catch-all namespace for YARP.
const yarp::os::LogComponent & RP2_LIDAR()