20 _serial = std::make_unique<Serial>(port);
23 _srv = std::make_unique<Cfg>(
mutex, private_nh);
29 ROS_INFO(
"Publishing toposens data to /%s", kScansTopic);
46 _serial = std::make_unique<Serial>(port);
49 _srv = std::make_unique<Cfg>(
mutex, private_nh);
55 ROS_INFO(
"Publishing toposens data to /%s", kScansTopic);
75 std::string data =
_buffer.str();
76 size_t frame_start = data.find(
'S');
78 int ack = (data[frame_start + 6] -
'0');
79 if (data[frame_start + 5] ==
'-') ack *= -1;
86 auto i = data.begin() + 8;
90 throw "Invalid acknowledgement error";
94 ROS_INFO(
"Firmware version could not be retrieved");
107 _scan.points.clear();
117 if (
_scan.points.empty())
162 ?
_cfg.external_temperature
168 ROS_INFO(
"Sensor settings initialized");
170 ROS_WARN(
"One or more settings failed to initialize");
182 if (level == 0b00000000)
return;
187 if ((
int)level >= 0b10000000)
189 ROS_INFO(
"Update skipped: Parameter not recognized");
194 if (level & 0b00000010)
205 if (level & 0b00000100)
216 if (level & 0b00001000)
227 if (level & 0b00010000)
238 if (level & 0b00100001)
243 ?
_cfg.external_temperature
292 auto i = frame.begin();
295 if (++i == frame.end())
return;
296 _scan.noisy = (*(++i) ==
'1');
298 for (i; i < frame.end(); ++i)
302 if (++i == frame.end())
return;
306 toposens_msgs::TsPoint pt;
307 pt.location.x =
_toNum(++i) / 1000.0;
310 pt.location.y =
_toNum(++i) / 1000.0;
312 throw std::invalid_argument(
"Expected Y-tag not found");
315 pt.location.z =
_toNum(++i) / 1000.0;
317 throw std::invalid_argument(
"Expected Z-tag not found");
320 pt.intensity =
_toNum(++i) / 100.0;
322 throw std::invalid_argument(
"Expected V-tag not found");
324 if (pt.intensity > 0)
_scan.points.push_back(pt);
326 catch (
const std::exception &e)
328 ROS_INFO(
"Skipped invalid point in stream");
329 ROS_DEBUG(
"Error: %s in message %s", e.what(), frame.c_str());
337 size_t frame_start = data.find(
'S');
338 int ack = (data[frame_start + 6] -
'0');
339 if (data[frame_start + 5] ==
'-') ack *= -1;
341 float val = std::atof(&data[frame_start + 8]);
352 if (rx_cmd ==
nullptr)
return false;
364 ? std::atof(&rx_cmd->
getBytes()[6]) / 10
365 : std::atof(&rx_cmd->
getBytes()[6])));
369 else if (strcmp(tx_cmd.
getBytes(),
"CsTemp-1000\r") == 0)
372 <<
" set to use internal temperature sensor.");
378 << std::atof(&rx_cmd->
getBytes()[6]));
393 _cfg.num_pulses = value;
395 _cfg.peak_detection_window = value;
397 _cfg.echo_rejection_threshold = value;
399 _cfg.external_temperature = value;
401 _cfg.noise_indicator_threshold = value;
415 std::size_t frame_start;
449 int abs = 0, factor = 1, length = 5;
455 throw std::invalid_argument(
"Invalid value char");
459 int d = *(++i) -
'0';
460 if (d >= 0 && d <= 9)
463 throw std::bad_cast();
466 return (
float)(factor * abs);
toposens_msgs::TsScan _scan
void _reconfig(TsDriverConfig &cfg, uint32_t level)
std::string getParamName()
void _synchronizeParameterValues()
std::stringstream _buffer
Command * _parseAck(const std::string &data)
Sensor(ros::NodeHandle nh, ros::NodeHandle private_nh)
static const int kQueueSize
void _displayFirmwareVersion()
void publish(const boost::shared_ptr< M > &message) const
bool _evaluateAck(Command &cmd, const std::string &frame)
bool getParam(const std::string &key, std::string &s) const
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
std::unique_ptr< Cfg > _srv
boost::recursive_mutex mutex
#define ROS_WARN_STREAM(args)
static const char kScansTopic[]
void setMode(ScanMode scan_mode)
void _updateConfig(TsParam param, int value)
#define ROS_INFO_STREAM(args)
#define USE_INTERNAL_TEMPERATURE
Generates firmware-compatible commands for tuning performance parameters.
std::unique_ptr< Serial > _serial
void _parse(const std::string &frame)