25#include <SimoxUtility/algorithm/string/string_tools.h>
34#include <HokuyoLaserScannerDriver/urg_utils.h>
53 ARMARX_INFO <<
"Going to report to listener " << laserScannerListenerProxyName;
58 std::vector<std::string> splitDeviceStrings =
Split(deviceStrings,
";");
60 devices.reserve(splitDeviceStrings.size());
61 for (std::string
const& deviceString : splitDeviceStrings)
63 std::vector<std::string> deviceInfo =
Split(deviceString,
",");
64 if (deviceInfo.size() != 3)
66 ARMARX_WARNING <<
"Unexpected format for laser scanner device: " << deviceString
67 <<
" (split size: " << deviceInfo.size() <<
")";
73 int port = std::stoi(deviceInfo[1]);
76 device.
ip = deviceInfo[0];
78 device.
frame = deviceInfo[2];
84 catch (std::exception
const& ex)
86 ARMARX_WARNING <<
"Could not convert port to integer for laser scanner device "
87 << deviceString <<
" (port is " << deviceInfo[1] <<
") : " << ex.what();
102 connectedDevices.clear();
108 device.task =
nullptr;
112 if (!device.reconnect())
114 ARMARX_WARNING <<
"Not starting task for laser scanner with IP: " << device.ip
115 <<
", Port: " << device.port;
120 heartbeat->signUp(device.ip,
123 {
"LaserScanner",
"Localization"},
124 "HokuyoLaserScanDevice");
126 LaserScannerInfo info;
127 info.device = device.ip;
128 info.frame = device.frame;
129 int minStep = 0, maxStep = 0;
130 urg_step_min_max(&device.urg, &minStep, &maxStep);
131 info.minAngle = urg_step2rad(&device.urg, minStep);
132 info.maxAngle = urg_step2rad(&device.urg, maxStep);
135 int lengthDataSize = urg_max_data_size(&device.urg);
136 info.stepSize = (info.maxAngle - info.minAngle) / (maxStep - minStep);
137 device.lengthData.resize(lengthDataSize);
139 device.listenerPrx = listenerPrx;
140 device.robotHealthPlugin = heartbeat;
141 device.debugObserver = debugObserver;
143 connectedDevices.push_back(info);
145 ARMARX_INFO <<
"Connected to " << device.ip <<
", " << info.frame <<
", " << info.minAngle
146 <<
", " << info.maxAngle <<
", " << info.stepSize;
150 device.task->start();
162 device.task =
nullptr;
164 if (device.connected)
166 urg_close(&device.urg);
167 device.connected =
false;
187 return laserScannerListenerProxyName;
193 return connectedDevices;
201 ARMARX_INFO <<
"Disconnecting from laser scanner with IP " <<
ip;
206 int ret = urg_open(&
urg, URG_ETHERNET,
ip.c_str(),
port);
210 ARMARX_WARNING <<
"Could not connect to laser scanner device using URG driver (IP: " <<
ip
211 <<
", Port: " <<
port <<
", Error: " << ret <<
")";
214 ret = urg_start_measurement(&
urg, URG_DISTANCE, URG_SCAN_INFINITY, 0);
224 <<
"Could not start measurement for laser scanner device using URG driver (IP: " <<
ip
225 <<
", Port: " <<
port <<
", Error: " << ret <<
")";
234 while (!
task->isStopped())
242 ARMARX_ERROR <<
"Device " <<
ip <<
" has too many consecutive errors!";
248 int lengthDataSize = urg_get_distance(&
urg,
lengthData.data(),
nullptr);
249 if (lengthDataSize < 0)
252 <<
"Could not get measurement for laser scanner (IP: " <<
ip
253 <<
", Port: " <<
port <<
", Error: " << lengthDataSize <<
")";
261 scan.reserve(lengthDataSize);
262 for (
int stepIndex = 0; stepIndex < lengthDataSize; ++stepIndex)
272 scan.push_back(step);
298 <<
", Port: " <<
port;
303 IceUtil::Time duration = time_topicHeartbeat - time_start;
306 durations[
"total_ms"] =
new Variant(duration.toMilliSecondsDouble());
307 durations[
"measure_ms"] =
308 new Variant((time_measure - time_start).toMilliSecondsDouble());
309 durations[
"update_ms"] =
310 new Variant((time_update - time_measure).toMilliSecondsDouble());
311 durations[
"proxy_report_ms"] =
312 new Variant((time_proxyReport - time_update).toMilliSecondsDouble());
313 durations[
"topic_health_ms"] =
314 new Variant((time_topicHeartbeat - time_proxyReport).toMilliSecondsDouble());
316 "LaserScannerDuration_" + simox::alg::replace_all(
ip,
".",
"_"), durations);
318 if (duration.toSecondsDouble() > 0.1)
321 <<
"Total time: " << duration.toMilliSecondsDouble() <<
"ms\n"
323 << (time_measure - time_start).toMilliSecondsDouble() <<
"ms \n"
325 << (time_update - time_measure).toMilliSecondsDouble() <<
"ms\n"
327 << (time_proxyReport - time_update).toMilliSecondsDouble() <<
"ms\n"
329 << (time_topicHeartbeat - time_proxyReport).toMilliSecondsDouble()
#define ARMARX_REGISTER_COMPONENT_EXECUTABLE(ComponentT, applicationName)
SpamFilterDataPtr deactivateSpam(SpamFilterDataPtr const &spamFilter, float deactivationDurationSec, const std::string &identifier, bool deactivate)
bool usingProxyFromProperty(const std::string &propertyName, const std::string &endpoints="")
Use a proxy whose name is specified by the given property.
void offeringTopicFromProperty(const std::string &propertyName)
Offer a topic whose name is specified by the given property.
ProxyType getProxyFromProperty(const std::string &propertyName, bool addToDependencies=false, const std::string &endpoints="", bool throwOnProxyError=true)
Get a proxy whose name is specified by the given property.
std::string getConfigIdentifier()
Retrieve config identifier for this component as set in constructor.
Property< PropertyType > getProperty(const std::string &name)
Brief description of class HokuyoLaserUnit.
void onInitComponent() override
LaserScannerInfoSeq getConnectedDevices(const Ice::Current &c) const override
void onDisconnectComponent() override
armarx::PropertyDefinitionsPtr createPropertyDefinitions() override
void onConnectComponent() override
std::string getReportTopicName(const Ice::Current &c) const override
void onExitComponent() override
TopicProxyType getTopic(const std::string &name)
Returns a proxy of the specified topic.
PluginT * addPlugin(const std::string prefix="", ParamsT &&... params)
std::string getName() const
Retrieve name of object.
static IceUtil::Time GetTime(TimeMode timeMode=TimeMode::VirtualTime)
Get the current time.
Implements a Variant type for timestamps.
The Variant class is described here: Variants.
static Duration MilliSeconds(std::int64_t milliSeconds)
Constructs a duration in milliseconds.
#define ARMARX_CHECK_NOT_NULL(ptr)
This macro evaluates whether ptr is not null and if it turns out to be false it will throw an Express...
#define ARMARX_INFO
The normal logging level.
#define ARMARX_IMPORTANT
The logging level for always important information, but expected behaviour (in contrast to ARMARX_WAR...
#define ARMARX_ERROR
The logging level for unexpected behaviour, that must be fixed.
#define ARMARX_WARNING
The logging level for unexpected behaviour, but not a serious problem.
This file offers overloads of toIce() and fromIce() functions for STL container types.
std::map< std::string, VariantBasePtr > StringVariantBaseMap
std::vector< std::string > Split(const std::string &source, const std::string &splitBy, bool trimElements=false, bool removeEmptyElements=false)
IceUtil::Handle< class PropertyDefinitionContainer > PropertyDefinitionsPtr
PropertyDefinitions smart pointer type.
IceInternal::Handle< TimestampVariant > TimestampVariantPtr
double distance(const Point &a, const Point &b)
LaserScannerUnitListenerPrx listenerPrx
std::vector< long > lengthData
RunningTask< HokuyoLaserScanDevice >::pointer_type task
DebugObserverInterfacePrx debugObserver
std::string componentName
armarx::plugins::HeartbeatComponentPlugin * robotHealthPlugin