25#include <SimoxUtility/algorithm/string/string_tools.h>
33#include <HokuyoLaserScannerDriver/urg_utils.h>
50 ARMARX_INFO <<
"Going to report to listener " << laserScannerListenerProxyName;
55 std::vector<std::string> splitDeviceStrings =
Split(deviceStrings,
";");
57 devices.reserve(splitDeviceStrings.size());
58 for (std::string
const& deviceString : splitDeviceStrings)
60 std::vector<std::string> deviceInfo =
Split(deviceString,
",");
61 if (deviceInfo.size() != 3)
63 ARMARX_WARNING <<
"Unexpected format for laser scanner device: " << deviceString
64 <<
" (split size: " << deviceInfo.size() <<
")";
70 int port = std::stoi(deviceInfo[1]);
73 device.
ip = deviceInfo[0];
75 device.
frame = deviceInfo[2];
81 catch (std::exception
const& ex)
83 ARMARX_WARNING <<
"Could not convert port to integer for laser scanner device "
84 << deviceString <<
" (port is " << deviceInfo[1] <<
") : " << ex.what();
99 connectedDevices.clear();
105 device.task =
nullptr;
109 if (!device.reconnect())
111 ARMARX_WARNING <<
"Not starting task for laser scanner with IP: " << device.ip
112 <<
", Port: " << device.port;
117 heartbeat->signUp(device.ip,
120 {
"LaserScanner",
"Localization"},
121 "HokuyoLaserScanDevice");
123 LaserScannerInfo info;
124 info.device = device.ip;
125 info.frame = device.frame;
126 int minStep = 0, maxStep = 0;
127 urg_step_min_max(&device.urg, &minStep, &maxStep);
128 info.minAngle = urg_step2rad(&device.urg, minStep);
129 info.maxAngle = urg_step2rad(&device.urg, maxStep);
132 int lengthDataSize = urg_max_data_size(&device.urg);
133 info.stepSize = (info.maxAngle - info.minAngle) / (maxStep - minStep);
134 device.lengthData.resize(lengthDataSize);
136 device.listenerPrx = listenerPrx;
137 device.robotHealthPlugin = heartbeat;
138 device.debugObserver = debugObserver;
140 connectedDevices.push_back(info);
142 ARMARX_INFO <<
"Connected to " << device.ip <<
", " << info.frame <<
", " << info.minAngle
143 <<
", " << info.maxAngle <<
", " << info.stepSize;
147 device.task->start();
159 device.task =
nullptr;
161 if (device.connected)
163 urg_close(&device.urg);
164 device.connected =
false;
184 return laserScannerListenerProxyName;
190 return connectedDevices;
198 ARMARX_INFO <<
"Disconnecting from laser scanner with IP " <<
ip;
203 int ret = urg_open(&
urg, URG_ETHERNET,
ip.c_str(),
port);
207 ARMARX_WARNING <<
"Could not connect to laser scanner device using URG driver (IP: " <<
ip
208 <<
", Port: " <<
port <<
", Error: " << ret <<
")";
211 ret = urg_start_measurement(&
urg, URG_DISTANCE, URG_SCAN_INFINITY, 0);
221 <<
"Could not start measurement for laser scanner device using URG driver (IP: " <<
ip
222 <<
", Port: " <<
port <<
", Error: " << ret <<
")";
231 while (!
task->isStopped())
239 ARMARX_ERROR <<
"Device " <<
ip <<
" has too many consecutive errors!";
245 int lengthDataSize = urg_get_distance(&
urg,
lengthData.data(),
nullptr);
246 if (lengthDataSize < 0)
249 <<
"Could not get measurement for laser scanner (IP: " <<
ip
250 <<
", Port: " <<
port <<
", Error: " << lengthDataSize <<
")";
258 scan.reserve(lengthDataSize);
259 for (
int stepIndex = 0; stepIndex < lengthDataSize; ++stepIndex)
269 scan.push_back(step);
295 <<
", Port: " <<
port;
300 IceUtil::Time duration = time_topicHeartbeat - time_start;
303 durations[
"total_ms"] =
new Variant(duration.toMilliSecondsDouble());
304 durations[
"measure_ms"] =
305 new Variant((time_measure - time_start).toMilliSecondsDouble());
306 durations[
"update_ms"] =
307 new Variant((time_update - time_measure).toMilliSecondsDouble());
308 durations[
"proxy_report_ms"] =
309 new Variant((time_proxyReport - time_update).toMilliSecondsDouble());
310 durations[
"topic_health_ms"] =
311 new Variant((time_topicHeartbeat - time_proxyReport).toMilliSecondsDouble());
313 "LaserScannerDuration_" + simox::alg::replace_all(
ip,
".",
"_"), durations);
315 if (duration.toSecondsDouble() > 0.1)
318 <<
"Total time: " << duration.toMilliSecondsDouble() <<
"ms\n"
320 << (time_measure - time_start).toMilliSecondsDouble() <<
"ms \n"
322 << (time_update - time_measure).toMilliSecondsDouble() <<
"ms\n"
324 << (time_proxyReport - time_update).toMilliSecondsDouble() <<
"ms\n"
326 << (time_topicHeartbeat - time_proxyReport).toMilliSecondsDouble()
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)
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