32 #ifndef _USE_MATH_DEFINES
33 #define _USE_MATH_DEFINES
38 #define DEG2RAD M_PI/180.0
45 using namespace rp::standalone::rplidar;
57 m_device_status = DEVICE_OK_STANBY;
63 if (this->parseConfiguration(config) ==
false)
69 bool br = config.check(
"GENERAL");
73 if (general_config.
check(
"serial_port") ==
false) {
yCError(
RP2_LIDAR) <<
"Missing serial_port param in GENERAL group";
return false; }
74 if (general_config.
check(
"serial_baudrate") ==
false) {
yCError(
RP2_LIDAR) <<
"Missing serial_baudrate param in GENERAL group";
return false; }
75 if (general_config.
check(
"sample_buffer_life") ==
false) {
yCError(
RP2_LIDAR) <<
"Missing sample_buffer_life param in GENERAL group";
return false; }
77 baudrate = general_config.
find(
"serial_baudrate").
asInt32();
78 m_serialPort = general_config.
find(
"serial_port").
asString();
79 m_buffer_life = general_config.
find(
"sample_buffer_life").
asInt32();
80 if (general_config.
check(
"motor_pwm"))
82 m_pwm_val = general_config.
find(
"motor_pwm").
asInt32();
84 if (general_config.
check(
"thread_period"))
86 double thread_period = general_config.
find(
"thread_period").
asInt32() / 1000.0;
87 this->setPeriod(thread_period);
96 m_drv = RPlidarDriver::CreateDriver(rp::standalone::rplidar::DRIVER_TYPE_SERIALPORT);
103 if (IS_FAIL(m_drv->connect(m_serialPort.c_str(), (_u32)baudrate)))
105 yCError(
RP2_LIDAR) <<
"Error, cannot bind to the specified serial port:", m_serialPort.c_str();
106 RPlidarDriver::DisposeDriver(m_drv);
110 m_info = deviceinfo();
111 yCInfo(
RP2_LIDAR,
"max_dist %f, min_dist %f", m_max_distance, m_min_distance);
113 bool m_inExpressMode=
false;
114 result = m_drv->checkExpressScanSupported(m_inExpressMode);
115 if (result == RESULT_OK && m_inExpressMode==
true)
124 result = m_drv->startMotor();
125 if (result != RESULT_OK)
134 if (m_pwm_val>0 && m_pwm_val<1023)
136 result = m_drv->setMotorPWM(m_pwm_val);
137 if (result != RESULT_OK)
146 yCError(
RP2_LIDAR) <<
"Invalid motor pwm request " << m_pwm_val <<
". It should be a value between 0 and 1023.";
155 bool forceScan =
false;
156 result = m_drv->startScan(forceScan,m_inExpressMode);
158 if (result != RESULT_OK)
166 yCInfo(
RP2_LIDAR,
"max_angle %f, min_angle %f", m_max_angle, m_min_angle);
169 PeriodicThread::start();
176 RPlidarDriver::DisposeDriver(m_drv);
177 PeriodicThread::stop();
184 std::lock_guard<std::mutex> guard(m_mutex);
185 m_min_distance = min;
186 m_max_distance = max;
192 std::lock_guard<std::mutex> guard(m_mutex);
200 std::lock_guard<std::mutex> guard(m_mutex);
207 std::lock_guard<std::mutex> guard(m_mutex);
219 #define _countof(_Array) (int)(sizeof(_Array) / sizeof (_Array[0]))
225 rplidar_response_measurement_node_t nodes[2048];
228 op_result = m_drv->grabScanData(nodes, count);
229 if (op_result != RESULT_OK)
232 handleError(op_result);
238 op_result = m_drv->getFrequency(m_inExpressMode, count, frequency, is4kmode);
239 if (op_result != RESULT_OK)
244 m_drv->ascendScanData(nodes, count);
246 if (op_result != RESULT_OK)
249 handleError(op_result);
253 if (m_buffer_life && life%m_buffer_life == 0)
255 for (
size_t i=0 ;i<m_laser_data.size(); i++)
258 m_laser_data[i]=std::numeric_limits<double>::infinity();
262 for (
size_t i = 0; i < count; ++i)
265 double distance = nodes[i].distance_q2 / 4.0f / 1000.0;
266 double angle = (float)((nodes[i].angle_q6_checkbit >> RPLIDAR_RESP_MEASUREMENT_ANGLE_SHIFT)/64.0f);
267 double quality = nodes[i].sync_quality >> RPLIDAR_RESP_MEASUREMENT_QUALITY_SHIFT;
268 angle = (360 - angle);
281 if (quality == 0 || distance == 0)
283 distance = std::numeric_limits<double>::infinity();
286 int elem = (int)(angle / m_resolution);
287 if (elem >= 0 && elem < (
int)m_laser_data.size())
289 m_laser_data[elem] = distance;
293 yCDebug(
RP2_LIDAR) <<
"RpLidar::run() invalid angle: elem" << elem <<
">" <<
"laser_data.size()" << m_laser_data.size();
296 applyLimitsOnLaserData();
312 void RpLidar2::handleError(u_result error)
316 case RESULT_FAIL_BIT:
319 case RESULT_ALREADY_DONE:
322 case RESULT_INVALID_DATA:
325 case RESULT_OPERATION_FAIL:
328 case RESULT_OPERATION_TIMEOUT:
331 case RESULT_OPERATION_STOP:
334 case RESULT_OPERATION_NOT_SUPPORT:
337 case RESULT_FORMAT_NOT_SUPPORT:
340 case RESULT_INSUFFICIENT_MEMORY:
346 std::string RpLidar2::deviceinfo()
351 rplidar_response_device_info_t info;
354 result = m_drv->getDeviceInfo(info);
355 if (result != RESULT_OK)
361 for (
unsigned char i : info.serialnum)
363 serialNumber += to_string(i);
366 return "Firmware Version: " + to_string(info.firmware_version) +
367 "\nHardware Version: " + to_string(info.hardware_version) +
368 "\nModel: " + to_string(info.model) +
369 "\nSerial Number:" + serialNumber;
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 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,...)
The main, catch-all namespace for YARP.
const yarp::os::LogComponent & RP2_LIDAR()