xdainterface.cpp
Go to the documentation of this file.
1 
2 // Copyright (c) 2003-2021 Xsens Technologies B.V. or subsidiaries worldwide.
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without modification,
6 // are permitted provided that the following conditions are met:
7 //
8 // 1. Redistributions of source code must retain the above copyright notice,
9 // this list of conditions, and the following disclaimer.
10 //
11 // 2. Redistributions in binary form must reproduce the above copyright notice,
12 // this list of conditions, and the following disclaimer in the documentation
13 // and/or other materials provided with the distribution.
14 //
15 // 3. Neither the names of the copyright holders nor the names of their contributors
16 // may be used to endorse or promote products derived from this software without
17 // specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
20 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
22 // THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
24 // OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY OR
26 // TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.THE LAWS OF THE NETHERLANDS
28 // SHALL BE EXCLUSIVELY APPLICABLE AND ANY DISPUTES SHALL BE FINALLY SETTLED UNDER THE RULES
29 // OF ARBITRATION OF THE INTERNATIONAL CHAMBER OF COMMERCE IN THE HAGUE BY ONE OR MORE
30 // ARBITRATORS APPOINTED IN ACCORDANCE WITH SAID RULES.
31 //
32 
33 #include "xdainterface.h"
34 
35 #include <xscontroller/xsscanner.h>
38 
56 
57 
58 
60  : m_device(nullptr)
61 {
62  ROS_INFO("Creating XsControl object...");
63  m_control = XsControl::construct();
64  assert(m_control != 0);
65 }
66 
68 {
69  ROS_INFO("Cleaning up ...");
70  close();
72 }
73 
74 void XdaInterface::spinFor(std::chrono::milliseconds timeout)
75 {
76  RosXsDataPacket rosPacket = m_xdaCallback.next(timeout);
77 
78  if (!rosPacket.second.empty())
79  {
80  for (auto &cb : m_callbacks)
81  {
82  cb->operator()(rosPacket.second, rosPacket.first);
83  }
84  }
85 }
86 
88 {
89  bool should_publish;
90 
91  if (ros::param::get("~pub_imu", should_publish) && should_publish)
92  {
93  registerCallback(new ImuPublisher(node));
94  }
95  if (ros::param::get("~pub_quaternion", should_publish) && should_publish)
96  {
98  }
99  if (ros::param::get("~pub_acceleration", should_publish) && should_publish)
100  {
102  }
103  if (ros::param::get("~pub_angular_velocity", should_publish) && should_publish)
104  {
106  }
107  if (ros::param::get("~pub_mag", should_publish) && should_publish)
108  {
110  }
111  if (ros::param::get("~pub_dq", should_publish) && should_publish)
112  {
114  }
115  if (ros::param::get("~pub_dv", should_publish) && should_publish)
116  {
118  }
119  if (ros::param::get("~pub_sampletime", should_publish) && should_publish)
120  {
122  }
123  if (ros::param::get("~pub_temperature", should_publish) && should_publish)
124  {
126  }
127  if (ros::param::get("~pub_pressure", should_publish) && should_publish)
128  {
130  }
131  if (ros::param::get("~pub_gnss", should_publish) && should_publish)
132  {
133  registerCallback(new GnssPublisher(node));
134  }
135  if (ros::param::get("~pub_twist", should_publish) && should_publish)
136  {
137  registerCallback(new TwistPublisher(node));
138  }
139  if (ros::param::get("~pub_free_acceleration", should_publish) && should_publish)
140  {
142  }
143  if (ros::param::get("~pub_transform", should_publish) && should_publish)
144  {
146  }
147  if (ros::param::get("~pub_positionLLA", should_publish) && should_publish)
148  {
150  }
151  if (ros::param::get("~pub_velocity", should_publish) && should_publish)
152  {
154  }
155 }
156 
158 {
159  // Read baudrate parameter if set
160  XsBaudRate baudrate = XBR_Invalid;
161  if (ros::param::has("~baudrate"))
162  {
163  int baudrateParam = 0;
164  ros::param::get("~baudrate", baudrateParam);
165  ROS_INFO("Found baudrate parameter: %d", baudrateParam);
166  baudrate = XsBaud::numericToRate(baudrateParam);
167  }
168  // Read device ID parameter
169  bool checkDeviceID = false;
170  std::string deviceId;
171  if (ros::param::has("~device_id"))
172  {
173  ros::param::get("~device_id", deviceId);
174  checkDeviceID = true;
175  ROS_INFO("Found device ID parameter: %s.",deviceId.c_str());
176 
177  }
178  // Read port parameter if set
179  XsPortInfo mtPort;
180  if (ros::param::has("~port"))
181  {
182  std::string portName;
183  ros::param::get("~port", portName);
184  ROS_INFO("Found port name parameter: %s", portName.c_str());
185  mtPort = XsPortInfo(portName, baudrate);
186  ROS_INFO("Scanning port %s ...", portName.c_str());
187  if (!XsScanner::scanPort(mtPort, baudrate))
188  return handleError("No MTi device found. Verify port and baudrate.");
189  if (checkDeviceID && mtPort.deviceId().toString().c_str() != deviceId)
190  return handleError("No MTi device found with matching device ID.");
191 
192  }
193  else
194  {
195  ROS_INFO("Scanning for devices...");
196  XsPortInfoArray portInfoArray = XsScanner::scanPorts(baudrate);
197 
198  for (auto const &portInfo : portInfoArray)
199  {
200  if (portInfo.deviceId().isMti() || portInfo.deviceId().isMtig())
201  {
202  if (checkDeviceID)
203  {
204  if (portInfo.deviceId().toString().c_str() == deviceId)
205  {
206  mtPort = portInfo;
207  break;
208  }
209  }
210  else
211  {
212  mtPort = portInfo;
213  break;
214  }
215  }
216  }
217  }
218 
219  if (mtPort.empty())
220  return handleError("No MTi device found.");
221 
222  ROS_INFO("Found a device with ID: %s @ port: %s, baudrate: %d", mtPort.deviceId().toString().toStdString().c_str(), mtPort.portName().toStdString().c_str(), XsBaud::rateToNumeric(mtPort.baudrate()));
223 
224  ROS_INFO("Opening port %s ...", mtPort.portName().toStdString().c_str());
225  if (!m_control->openPort(mtPort))
226  return handleError("Could not open port");
227 
228  m_device = m_control->device(mtPort.deviceId());
229  assert(m_device != 0);
230 
231  ROS_INFO("Device: %s, with ID: %s opened.", m_device->productCode().toStdString().c_str(), m_device->deviceId().toString().c_str());
232 
234 
235  return true;
236 }
237 
238 bool XdaInterface::configureOutput(unsigned int sampling_frequency,
239  unsigned int enable_acceleration,
240  unsigned int enable_angular_velocity,
241  unsigned int enable_orientation)
242 {
243  assert(m_device != 0);
244 
245  ROS_INFO("Putting device into configuration mode...");
246  if (!m_device->gotoConfig())
247  return handleError("Could not put device into configuration mode");
248 
249  ROS_INFO("Configuring the device...");
250  XsOutputConfigurationArray configArray;
251 
252  if (m_device->deviceId().isMti())
253  {
254  configArray.push_back(XsOutputConfiguration(XDI_PacketCounter, 0));
255  configArray.push_back(XsOutputConfiguration(XDI_SampleTimeFine, 0));
256  if (enable_acceleration)
257  configArray.push_back(XsOutputConfiguration(XDI_Acceleration, sampling_frequency));
258  if (enable_angular_velocity)
259  configArray.push_back(XsOutputConfiguration(XDI_RateOfTurn, sampling_frequency));
260  if (enable_orientation)
261  configArray.push_back(XsOutputConfiguration(XDI_Quaternion, sampling_frequency));
262  }
263  else
264  {
265  throw std::runtime_error("No IMU device while configuring. Aborting.");
266  }
267 
268  if (!m_device->setOutputConfiguration(configArray))
269  {
270  return handleError("Could not configure MTi device. Aborting.");
271  }
272 
273  return true;
274 }
275 
277 {
278  assert(m_device != 0);
279 
280  if (!m_device->gotoConfig())
281  return handleError("Could not go to config");
282 
283  std::string filter_profile;
284  if (ros::param::param("~filter_profile", filter_profile, filter_profile))
285  {
286  ROS_INFO("Setting filter profile to '%s'", filter_profile.c_str());
287  if (!m_device->setOnboardFilterProfile(filter_profile))
288  ROS_ERROR("Could not configure filter profile");
289  }
290 
291  // read EMTS and device config stored in .mtb file header.
293  return handleError("Could not read device configuration");
294 
295  ROS_INFO("Measuring ...");
296  if (!m_device->gotoMeasurement())
297  return handleError("Could not put device into measurement mode");
298 
299  std::string logFile;
300  if (ros::param::get("~log_file", logFile))
301  {
302  if (m_device->createLogFile(logFile) != XRV_OK)
303  return handleError("Failed to create a log file! (" + logFile + ")");
304  else
305  ROS_INFO("Created a log file: %s", logFile.c_str());
306 
307  ROS_INFO("Recording to %s ...", logFile.c_str());
308  if (!m_device->startRecording())
309  return handleError("Could not start recording");
310  }
311 
312  return true;
313 }
314 
316 {
317  if (m_device != nullptr)
318  {
322  }
324 }
325 
327 {
328  m_callbacks.push_back(cb);
329 }
330 
331 bool XdaInterface::handleError(std::string error)
332 {
333  ROS_ERROR("%s", error.c_str());
334  close();
335  return false;
336 }
XsOutputConfiguration
struct XsOutputConfiguration XsOutputConfiguration
Definition: xsoutputconfiguration.h:118
TemperaturePublisher
Definition: temperaturepublisher.h:39
XsDevice::deviceId
XsDeviceId const & deviceId() const
Return the device ID of the device.
Definition: xsdevice_def.cpp:742
XsControl::openPort
bool openPort(const XsString &portname, XsBaudRate baudrate, uint32_t timeout=0, bool detectRs485=false)
Open a communication channel on serial port with the given portname.
Definition: xscontrol_def.cpp:684
XDI_RateOfTurn
@ XDI_RateOfTurn
Rate of turn data in rad/sec.
Definition: xsdataidentifier.h:152
orientationincrementspublisher.h
ros::param::get
ROSCPP_DECL bool get(const std::string &key, bool &b)
XdaInterface::registerCallback
void registerCallback(PacketCallback *cb)
Definition: xdainterface.cpp:326
TransformPublisher
Definition: transformpublisher.h:40
XdaInterface::~XdaInterface
~XdaInterface()
Definition: list_filter_profiles.cpp:18
transformpublisher.h
packetcallback.h
XsControl::closePort
void closePort(const XsString &portname)
Close the serial port with the given portname.
Definition: xscontrol_def.cpp:260
imupublisher.h
TimeReferencePublisher
Definition: timereferencepublisher.h:39
PressurePublisher
Definition: pressurepublisher.h:39
positionllapublisher.h
OrientationIncrementsPublisher
Definition: orientationincrementspublisher.h:39
XsDevice::createLogFile
XsResultValue createLogFile(const XsString &filename)
Create a log file for logging.
Definition: xsdevice_def.cpp:2038
OrientationPublisher
Definition: orientationpublisher.h:39
RosXsDataPacket
std::pair< ros::Time, XsDataPacket > RosXsDataPacket
Definition: xdacallback.h:43
XdaInterface::m_callbacks
std::list< PacketCallback * > m_callbacks
Definition: xdainterface.h:72
XsDevice::productCode
virtual XsString productCode() const
Return the product code of the device.
Definition: xsdevice_def.cpp:3451
XsControl::construct
static XSNOEXPORT XsControl * construct()
Definition: xscontrol_def.cpp:1183
CallbackManagerXda::removeCallbackHandler
void removeCallbackHandler(XsCallbackPlainC *cb, bool chain=true)
Remove a handler from the list.
Definition: callbackmanagerxda.cpp:207
timereferencepublisher.h
XRV_OK
@ XRV_OK
0: Operation was performed successfully
Definition: xsresultvalue.h:85
XdaInterface::m_device
XsDevice * m_device
Definition: list_filter_profiles.cpp:124
XDI_PacketCounter
@ XDI_PacketCounter
Packet counter, increments every packet.
Definition: xsdataidentifier.h:107
XsDevice::stopRecording
virtual bool stopRecording()
Stop recording incoming data.
Definition: xsdevice_def.cpp:2201
XDI_Quaternion
@ XDI_Quaternion
Orientation in quaternion format.
Definition: xsdataidentifier.h:122
magneticfieldpublisher.h
XdaCallback::next
RosXsDataPacket next(const std::chrono::milliseconds &timeout)
Definition: xdacallback.cpp:48
XdaInterface::m_xdaCallback
XdaCallback m_xdaCallback
Definition: xdainterface.h:71
XsOutputConfigurationArray
A list of XsOutputConfiguration values.
xscontrol_def.h
pressurepublisher.h
velocityincrementpublisher.h
XsPortInfo
struct XsPortInfo XsPortInfo
Definition: xsportinfo.h:83
XdaInterface::configureOutput
bool configureOutput(unsigned int sampling_frequency, unsigned int enable_acceleration, unsigned int enable_angular_velocity, unsigned int enable_orientation)
Definition: xdainterface.cpp:238
XsBaudRate
enum XsBaudRate XsBaudRate
Communication speed.
Definition: xsbaud.h:81
VelocityIncrementPublisher
Definition: velocityincrementpublisher.h:39
XsDevice::setOutputConfiguration
bool setOutputConfiguration(XsOutputConfigurationArray &config)
Set the output configuration for this device.
Definition: xsdevice_def.cpp:1138
XsPortInfo
Contains a descriptor for opening a communication port to an Xsens device.
Definition: xsportinfo.h:128
velocitypublisher.h
XsControl::destruct
XSNOEXPORT void destruct()
Definition: xscontrol_def.h:205
XdaInterface::handleError
bool handleError(std::string error)
Definition: xdainterface.cpp:331
XdaInterface::connectDevice
bool connectDevice()
Definition: list_filter_profiles.cpp:25
XdaInterface::spinFor
void spinFor(std::chrono::milliseconds timeout)
Definition: xdainterface.cpp:74
xsdevice_def.h
XsDevice::setOnboardFilterProfile
virtual bool setOnboardFilterProfile(int profileType)
Sets the filter profile to use for computing orientations on the device.
Definition: xsdevice_def.cpp:2659
XdaInterface::registerPublishers
void registerPublishers(ros::NodeHandle &node)
Definition: xdainterface.cpp:87
AngularVelocityPublisher
Definition: angularvelocitypublisher.h:39
XsDevice::startRecording
virtual bool startRecording()
Start recording incoming data.
Definition: xsdevice_def.cpp:2171
XdaInterface::prepare
bool prepare()
Definition: xdainterface.cpp:276
FreeAccelerationPublisher
Definition: freeaccelerationpublisher.h:39
XsControl::device
XsDevice * device(const XsDeviceId &deviceId) const
Returns the XsDevice interface object associated with the supplied deviceId.
Definition: xscontrol_def.cpp:947
XdaInterface::m_port
XsPortInfo m_port
Definition: xdainterface.h:70
XsPortInfoArray
A list of XsPortInfo values.
GnssPublisher
Definition: gnsspublisher.h:43
AccelerationPublisher
Definition: accelerationpublisher.h:39
xdainterface.h
XdaInterface::close
void close()
Definition: xdainterface.cpp:315
VelocityPublisher
Definition: velocitypublisher.h:39
XsDevice::readEmtsAndDeviceConfiguration
virtual XSNOEXPORT bool readEmtsAndDeviceConfiguration()
XsDevice::closeLogFile
virtual bool closeLogFile()
Close the log file.
Definition: xsdevice_def.cpp:2150
XdaInterface::XdaInterface
XdaInterface()
Definition: list_filter_profiles.cpp:12
MagneticFieldPublisher
Definition: magneticfieldpublisher.h:39
temperaturepublisher.h
accelerationpublisher.h
XsDevice::gotoConfig
virtual bool gotoConfig()
Put the device in config mode.
Definition: xsdevice_def.cpp:1014
PacketCallback
Definition: packetcallback.h:41
twistpublisher.h
ROS_ERROR
#define ROS_ERROR(...)
XsDevice::gotoMeasurement
virtual bool gotoMeasurement()
Put this device in measurement mode.
Definition: xsdevice_def.cpp:960
ImuPublisher
Definition: imupublisher.h:61
ros::param::param
T param(const std::string &param_name, const T &default_val)
PositionLLAPublisher
Definition: positionllapublisher.h:39
angularvelocitypublisher.h
XDI_Acceleration
@ XDI_Acceleration
Acceleration output in m/s2.
Definition: xsdataidentifier.h:131
ros::param::has
ROSCPP_DECL bool has(const std::string &key)
XDI_SampleTimeFine
@ XDI_SampleTimeFine
Sample Time Fine.
Definition: xsdataidentifier.h:111
XdaInterface::m_control
XsControl * m_control
Definition: list_filter_profiles.cpp:123
ROS_INFO
#define ROS_INFO(...)
xsscanner.h
orientationpublisher.h
XBR_Invalid
XBR_Invalid
Not a valid baud rate.
Definition: xsbaudrate.h:126
gnsspublisher.h
freeaccelerationpublisher.h
ros::NodeHandle
TwistPublisher
Definition: twistpublisher.h:39
CallbackManagerXda::addCallbackHandler
void addCallbackHandler(XsCallbackPlainC *cb, bool chain=true)
Add a handler to the list.
Definition: callbackmanagerxda.cpp:158


xsens_mti_driver
Author(s):
autogenerated on Sun Sep 3 2023 02:43:20