mocap_node.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2018, Houston Mechatronics Inc., JD Yamokoski
3  * Copyright (c) 2012, Clearpath Robotics, Inc., Alex Bencz
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright notice,
10  * this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  * 3. Neither the name of the copyright holder nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28  * POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 // Local includes
32 #include <mocap_optitrack/socket.h>
36 #include <mocap_optitrack/MocapOptitrackConfig.h>
37 #include "natnet/natnet_messages.h"
38 
39 #include <dynamic_reconfigure/server.h>
40 #include <memory>
41 #include <ros/ros.h>
42 
43 
44 namespace mocap_optitrack
45 {
46 
48 {
49 public:
51  ServerDescription const& serverDescr,
52  PublisherConfigurations const& pubConfigs) :
53  nh(nh), server(ros::NodeHandle("~/optitrack_config"))
54  {
55  server.setCallback(boost::bind(&OptiTrackRosBridge::reconfigureCallback, this, _1, _2));
56  serverDescription = serverDescr;
57  publisherConfigurations = pubConfigs;
58  }
59 
60  void reconfigureCallback(MocapOptitrackConfig& config, uint32_t)
61  {
62  serverDescription.enableOptitrack = config.enable_optitrack;
63  serverDescription.commandPort = config.command_port;
64  serverDescription.dataPort = config.data_port;
65  serverDescription.multicastIpAddress = config.multicast_address;
66 
67  initialize();
68  }
69 
70  void initialize()
71  {
73  {
74  // Create socket
78 
79  if (!serverDescription.version.empty())
80  {
82  }
83 
84  // Need verion information from the server to properly decode any of their packets.
85  // If we have not recieved that yet, send another request.
86  while (ros::ok() && !dataModel.hasServerInfo())
87  {
88  natnet::ConnectionRequestMessage connectionRequestMsg;
89  natnet::MessageBuffer connectionRequestMsgBuffer;
90  connectionRequestMsg.serialize(connectionRequestMsgBuffer, NULL);
91  int ret = multicastClientSocketPtr->send(
92  &connectionRequestMsgBuffer[0],
93  connectionRequestMsgBuffer.size(),
95  if (updateDataModelFromServer()) usleep(10);
96  else sleep(1);
97 
98  ros::spinOnce();
99  }
100  // Once we have the server info, create publishers
101  publishDispatcherPtr.reset(
105  ROS_INFO("Initialization complete");
106  initialized = true;
107  }
108  else
109  {
110  ROS_INFO("Initialization incomplete");
111  initialized = false;
112  }
113  };
114 
115  void run()
116  {
117  while (ros::ok())
118  {
119  if (initialized)
120  {
122  {
123  // Maybe we got some data? If we did it would be in the form of one or more
124  // rigid bodies in the data model
125  ros::Time time = ros::Time::now();
127 
128  // Clear out the model to prepare for the next frame of data
129  dataModel.clear();
130  }
131  // whether receive or nor, give a short break to relieft the CPU load due to while()
132  usleep(100);
133  }
134  else
135  {
136  ros::Duration(1.).sleep();
137  }
138  ros::spinOnce();
139  }
140  }
141 
142 private:
144  {
145  // Get data from mocap server
146  int numBytesReceived = multicastClientSocketPtr->recv();
147  if (numBytesReceived > 0)
148  {
149  // Grab latest message buffer
150  const char* pMsgBuffer = multicastClientSocketPtr->getBuffer();
151 
152  // Copy char* buffer into MessageBuffer and dispatch to be deserialized
153  natnet::MessageBuffer msgBuffer(pMsgBuffer, pMsgBuffer + numBytesReceived);
155 
156  return true;
157  }
158 
159  return false;
160  };
161 
166  std::unique_ptr<UdpMulticastSocket> multicastClientSocketPtr;
167  std::unique_ptr<RigidBodyPublishDispatcher> publishDispatcherPtr;
168  dynamic_reconfigure::Server<MocapOptitrackConfig> server;
170 };
171 
172 } // namespace mocap_optitrack
173 
174 
176 int main(int argc, char* argv[])
177 {
178  // Initialize ROS node
179  ros::init(argc, argv, "mocap_node");
180  ros::NodeHandle nh("~");
181 
182  // Grab node configuration from rosparam
185  mocap_optitrack::NodeConfiguration::fromRosParam(nh, serverDescription, publisherConfigurations);
186 
187  // Create node object, initialize and run
188  mocap_optitrack::OptiTrackRosBridge node(nh, serverDescription, publisherConfigurations);
189  node.initialize();
190  node.run();
191 
192  return 0;
193 }
static void dispatch(MessageBuffer const &, mocap_optitrack::DataModel *)
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
PublisherConfigurations publisherConfigurations
Definition: mocap_node.cpp:164
OptiTrackRosBridge(ros::NodeHandle &nh, ServerDescription const &serverDescr, PublisherConfigurations const &pubConfigs)
Definition: mocap_node.cpp:50
static void fromRosParam(ros::NodeHandle &nh, ServerDescription &serverDescription, PublisherConfigurations &pubConfigs)
Version const & getNatNetVersion() const
Definition: data_model.cpp:94
std::vector< char > MessageBuffer
std::vector< RigidBody > rigidBodies
Definition: data_model.h:105
#define ROS_INFO(...)
Dispatches RigidBody data to the correct publisher.
ROSCPP_DECL bool ok()
bool hasServerInfo() const
Definition: data_model.h:132
int main(int argc, char *argv[])
Definition: mocap_node.cpp:176
dynamic_reconfigure::Server< MocapOptitrackConfig > server
Definition: mocap_node.cpp:168
The data model for this node.
Definition: data_model.h:119
std::unique_ptr< UdpMulticastSocket > multicastClientSocketPtr
Definition: mocap_node.cpp:166
std::vector< PublisherConfiguration > PublisherConfigurations
Definition: mocap_config.h:77
virtual void serialize(MessageBuffer &msgBuffer, mocap_optitrack::DataModel const *)
std::unique_ptr< RigidBodyPublishDispatcher > publishDispatcherPtr
Definition: mocap_node.cpp:167
static Time now()
Allows to retrieve data from a UDP multicast group.
Definition: socket.h:55
void reconfigureCallback(MocapOptitrackConfig &config, uint32_t)
Definition: mocap_node.cpp:60
bool sleep() const
void setVersions(int *nver, int *sver)
Definition: data_model.cpp:87
ROSCPP_DECL void spinOnce()
Server communication info.
Definition: mocap_config.h:42


mocap_optitrack
Author(s): Kathrin Gräve , Alex Bencz/ , Tony Baltovski , JD Yamokoski
autogenerated on Mon Feb 28 2022 22:49:22