vicon
ViconDriver.cpp
Go to the documentation of this file.
1 #include "ViconDriver.hpp"
2 #include "Client.h"
3 
4 #include <sstream>
5 #include <time.h>
6 #include <base-logging/Logging.hpp>
7 
8 using namespace vicon;
9 using namespace ViconDataStreamSDK::CPP;
10 
11 namespace vicon {
12  class DriverImpl
13  {
14  public:
16  };
17 }
18 
19 int axesMap ( Direction::Enum axis ) {
20  switch ( axis ) {
21  case Direction::Up: return 3;
22  case Direction::Down: return -3;
23  case Direction::Left: return 2;
24  case Direction::Right: return -2;
25  case Direction::Forward: return 1;
26  case Direction::Backward: return -1;
27  default: return 0;
28  }
29 }
30 
31 Direction::Enum axesMap ( int axis ) {
32  int axis_val = axis < 0 ? -axis : axis;
33  switch ( axis_val ) {
34  case 1:
35  if ( axis > 0 ) return Direction::Forward;
36  else return Direction::Backward;
37  case 2:
38  if ( axis > 0 ) return Direction::Left;
39  else return Direction::Right;
40  case 3:
41  if ( axis > 0 ) return Direction::Up;
42  else return Direction::Down;
43  default:
44  return Direction::Forward;
45  }
46 }
47 
49  : impl( new DriverImpl() ), mLastResult(UNKNOWN)
50 {
51 }
52 
53 bool Driver::connect( const std::string& hostname, const unsigned int port )
54 {
55  std::ostringstream host;
56  host << hostname << ":" << port;
57  LOG_INFO_S << "connecting to " << host.str();
58 
59  impl->client.Connect( host.str() );
60 
61  if( isConnected() )
62  {
63  impl->client.EnableSegmentData();
64  impl->client.EnableUnlabeledMarkerData();
65 
66  //impl->client.SetStreamMode( ViconDataStreamSDK::CPP::StreamMode::ClientPull );
67  impl->client.SetStreamMode( ViconDataStreamSDK::CPP::StreamMode::ClientPullPreFetch );
68  // MyClient.SetStreamMode( ViconDataStreamSDK::CPP::StreamMode::ServerPush );
69 
70  // Set the global up axis
71  impl->client.SetAxisMapping(
74  Direction::Up ); // Z-up
75 
76  return true;
77  }
78  else
79  return false;
80 }
81 
83 {
84  return impl->client.IsConnected().Connected;
85 }
86 
88 {
89  LOG_INFO_S << "disconnecting";
90  impl->client.Disconnect();
91 }
92 
93 bool Driver::getFrame( const base::Time& timeout )
94 {
95  base::Time start = base::Time::now();
96  Result::Enum result;
97  while( ((result=impl->client.GetFrame().Result) == Result::NoFrame) && (start+timeout > base::Time::now()) )
98  {
99  const unsigned long wait_ms = 10;
100 #ifdef WIN32
101  Sleep( wait_ms );
102 #else
103  usleep( wait_ms );
104 #endif
105  }
106 
107  if( result == Result::Success )
108  {
109  LOG_DEBUG_S << "Got Frame!";
110  return true;
111  }
112  else
113  {
114  if ( timeout.toSeconds() > 0 ) LOG_ERROR_S << "No Frame received!";
115  return false;
116  }
117 }
118 
120 {
121  // for now, just return the current time
122  return base::Time::now();
123 }
124 
125 Eigen::Affine3d Driver::getSegmentTransform( const std::string& subjectName, const std::string& segmentName, bool& inFrame)
126 {
127 
128  // Get the segment name
129  std::string SegmentName = impl->client.GetSubjectRootSegmentName(subjectName).SegmentName;
130 
131  LOG_DEBUG_S << " Name: " << SegmentName;
132 
133  LOG_DEBUG_S << "get transform: " << subjectName << "." << segmentName;
135  impl->client.GetSegmentGlobalTranslation( subjectName, segmentName );
136 
138  impl->client.GetSegmentGlobalRotationQuaternion( subjectName, segmentName );
139 
140  Eigen::Vector3d trans_m( trans.Translation[0], trans.Translation[1], trans.Translation[2] );
141 
142  // vicon data is in mm, but we prefer standard si units...
143  Eigen::Affine3d result = Eigen::Translation3d( trans_m * 1e-3 ) *
144  Eigen::Quaterniond( quat.Rotation[3], quat.Rotation[0], quat.Rotation[1], quat.Rotation[2] );
145 
146  inFrame = !trans.Occluded;
147 
148  switch(trans.Result) {
150  mLastResult = INVALID_SUBJECT_NAME;
151  break;
153  mLastResult = INVALID_SEGMENT_NAME;
154  break;
155  case(Result::Success):
156  mLastResult = SUCCESS;
157  break;
158  default:
159  mLastResult = UNKNOWN;
160  break;
161  }
162 
163  return result;
164 }
165 
166 std::vector<base::Vector3d> Driver::getUnlabeledMarkers()
167 {
168  std::vector<base::Vector3d> result;
169 
170  unsigned int UnlabeledMarkerCount = impl->client.GetUnlabeledMarkerCount().MarkerCount;
171  for( unsigned int UnlabeledMarkerIndex = 0 ; UnlabeledMarkerIndex < UnlabeledMarkerCount ; ++UnlabeledMarkerIndex )
172  {
173  Output_GetUnlabeledMarkerGlobalTranslation _Output_GetUnlabeledMarkerGlobalTranslation =
174  impl->client.GetUnlabeledMarkerGlobalTranslation( UnlabeledMarkerIndex );
175 
176  Eigen::Vector3d marker_pos(
177  _Output_GetUnlabeledMarkerGlobalTranslation.Translation[ 0 ],
178  _Output_GetUnlabeledMarkerGlobalTranslation.Translation[ 1 ],
179  _Output_GetUnlabeledMarkerGlobalTranslation.Translation[ 2 ] );
180 
181  result.push_back( marker_pos * 1e-3 );
182  }
183 
184  return result;
185 }
186 
187 
188 void Driver::getAxesDir( int& x_dir, int& y_dir, int& z_dir )
189 {
190  Output_GetAxisMapping vicon_axes = impl->client.GetAxisMapping ();
191  x_dir = axesMap( vicon_axes.XAxis );
192  y_dir = axesMap( vicon_axes.YAxis );
193  z_dir = axesMap( vicon_axes.ZAxis );
194 }
195 
196 void Driver::setAxesDir( int x_dir, int y_dir, int z_dir )
197 {
198  impl->client.SetAxisMapping( axesMap(x_dir), axesMap(y_dir), axesMap(z_dir) );
199 
200 }
bool isConnected()
Definition: ViconDriver.cpp:82
void disconnect()
Definition: ViconDriver.cpp:87
void setAxesDir(int x_dir, int y_dir, int z_dir)
Set axes directions.
void getAxesDir(int &x_dir, int &y_dir, int &z_dir)
Get axes direction.
int axesMap(Direction::Enum axis)
Definition: ViconDriver.cpp:19
Eigen::Affine3d getSegmentTransform(const std::string &subjectName, const std::string &segmentName, bool &inFrame)
bool connect(const std::string &hostname, const unsigned int port=801)
Definition: ViconDriver.cpp:53
bool getFrame(const base::Time &timeout=base::Time::fromSeconds(1.0))
Definition: ViconDriver.cpp:93
std::vector< base::Vector3d > getUnlabeledMarkers()
base::Time getTimestamp()