OSVR Framework (Internal Development Docs)  0.6-1962-g59773924
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
osvr_log_to_csv.cpp
Go to the documentation of this file.
1 
11 // Copyright 2015 Sensics, Inc.
12 //
13 // Licensed under the Apache License, Version 2.0 (the "License");
14 // you may not use this file except in compliance with the License.
15 // You may obtain a copy of the License at
16 //
17 // http://www.apache.org/licenses/LICENSE-2.0
18 //
19 // Unless required by applicable law or agreed to in writing, software
20 // distributed under the License is distributed on an "AS IS" BASIS,
21 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 // See the License for the specific language governing permissions and
23 // limitations under the License.
24 
25 // Internal Includes
26 #include <osvr/Util/CSV.h>
27 #include <osvr/ClientKit/Context.h>
29 #include <osvr/Util/TimeValue.h>
30 
31 // Library/third-party includes
32 // - none
33 
34 // Standard includes
35 #include <iostream>
36 #include <fstream>
37 #include <chrono>
38 #include <thread>
39 
40 osvr::util::CSV g_csvOutput;
41 
42 static const auto MAX_ROWS = 1000;
43 static std::size_t g_markRows = 0;
44 static const auto MAX_SECONDS = 10;
45 
46 static const auto OUTFILE = "osvrdata.csv";
47 
48 using our_clock = std::chrono::system_clock;
49 
50 using osvr::util::cell;
51 
52 template <typename T> inline bool shouldStop(T const &deadline) {
53  return (g_csvOutput.numDataRows() - g_markRows) > MAX_ROWS ||
54  our_clock::now() > deadline;
55 }
56 
58 operator<<(osvr::util::CSV::RowProxy &&row,
59  osvr::util::time::TimeValue const &ts) {
60  return std::move(row) << osvr::util::cell("ts:seconds", ts.seconds)
61  << osvr::util::cell("ts:microseconds",
62  ts.microseconds);
63 }
64 
65 static void poseCallback(void *userdata, const OSVR_TimeValue *timestamp,
66  const OSVR_PoseReport *report) {
67  auto path = static_cast<char *>(userdata);
68  g_csvOutput.row()
69  << (*timestamp)
70  << cell(path + std::string{":x"}, report->pose.translation.data[0])
71  << cell(path + std::string{":y"}, report->pose.translation.data[1])
72  << cell(path + std::string{":z"}, report->pose.translation.data[2])
73  << cell(path + std::string{":qx"},
74  osvrQuatGetX(&(report->pose.rotation)))
75  << cell(path + std::string{":qy"},
76  osvrQuatGetY(&(report->pose.rotation)))
77  << cell(path + std::string{":qz"},
78  osvrQuatGetZ(&(report->pose.rotation)))
79  << cell(path + std::string{":qw"},
80  osvrQuatGetW(&(report->pose.rotation)));
81 }
82 
83 int main(int argc, char *argv[]) {
84  osvr::clientkit::ClientContext context("org.osvr.tools.logtocsv");
85 
86  for (int i = 1; i < argc; ++i) {
87  auto path = argv[i];
88  std::cerr << "Setting up data output for " << path << std::endl;
89  auto resource = context.getInterface(path);
90  resource.registerCallback(&poseCallback, path);
91  // will just let the context free them on exit.
92  }
93 
94  if (!context.checkStatus()) {
95  std::cerr << "Client context has not yet started up - waiting. Make "
96  "sure the server is running."
97  << std::endl;
98  do {
99  std::this_thread::sleep_for(std::chrono::milliseconds(1));
100  context.update();
101  } while (!context.checkStatus());
102  std::cerr << "OK, client context ready. Proceeding." << std::endl;
103  }
104  std::cerr << "Will exit after " << MAX_ROWS << " rows of data or "
105  << MAX_SECONDS << " seconds of runtime, whichever comes first."
106  << std::endl;
107 
108  auto begin = our_clock::now();
109  auto runTimeLimit = begin + std::chrono::seconds(MAX_SECONDS);
110  do {
111  context.update();
112  } while (!shouldStop(runTimeLimit));
114  std::cerr << "Writing " << g_csvOutput.numDataRows() << " data rows to "
115  << OUTFILE << std::endl;
116  {
117  std::ofstream outfile(OUTFILE, std::ios::out | std::ios::binary);
118  g_csvOutput.output(outfile);
119  outfile.close();
120  }
121  std::cerr << "Done!" << std::endl;
122  return 0;
123 }
OSVR_PoseState pose
The pose structure, containing a position vector and a rotation quaternion.
Client context object: Create and keep one in your application. Handles lifetime management and provi...
Definition: Context_decl.h:57
double osvrQuatGetY(OSVR_Quaternion const *q)
Accessor for quaternion component Y.
Definition: QuaternionC.h:66
bool checkStatus() const
Checks to see if the client context is properly and fully started up.
Definition: Context.h:111
OSVR_Quaternion rotation
Orientation as a unit quaternion.
Definition: Pose3C.h:58
Header.
double data[3]
Internal array data.
Definition: Vec3C.h:50
void output(std::ostream &os) const
Definition: CSV.h:340
Interface getInterface(const std::string &path)
Get the interface associated with the given path.
Definition: Context.h:61
double osvrQuatGetX(OSVR_Quaternion const *q)
Accessor for quaternion component X.
Definition: QuaternionC.h:65
Header providing a C++ wrapper around TimeValueC.h.
Header.
std::size_t numDataRows() const
Definition: CSV.h:261
int main(int argc, char *argv[])
void update()
Updates the state of the context - call regularly in your mainloop.
Definition: Context.h:54
OSVR_TimeValue_Microseconds microseconds
Microseconds portion of the time value.
Definition: TimeValueC.h:85
double osvrQuatGetW(OSVR_Quaternion const *q)
Accessor for quaternion component W.
Definition: QuaternionC.h:64
RowProxy row()
Definition: CSV.h:255
Header containing the inline implementation of Interface.
Standardized, portable parallel to struct timeval for representing both absolute times and time inter...
Definition: TimeValueC.h:81
double osvrQuatGetZ(OSVR_Quaternion const *q)
Accessor for quaternion component Z.
Definition: QuaternionC.h:67
OSVR_Vec3 translation
Position vector.
Definition: Pose3C.h:56
detail::Cell< T > cell(const char *header, T const &data)
Helper free function to make a CSV cell.
Definition: CSV.h:401
Report type for a pose (position and orientation) callback on a tracker interface.
OSVR_TimeValue_Seconds seconds
Seconds portion of the time value.
Definition: TimeValueC.h:83