38 #include <boost/program_options.hpp> 
   39 #include <boost/thread/thread.hpp> 
   40 #include <boost/date_time/posix_time/posix_time.hpp> 
   41 #include <json/value.h> 
   42 #include <json/reader.h> 
   53 auto SETTLE_TIME = boost::posix_time::seconds(2);
 
   55 static const double minAbsRadians = 1.5;
 
   56 static const int totalDots = 10;
 
   58 inline Eigen::Quaterniond
 
   65         cerr << 
"Sorry, no orientation state available for this route - " 
   66                 "are you sure you have a device plugged in and your " 
   67                 "path correct?" << endl;
 
   69         throw std::runtime_error(
"No orientation state available");
 
   76     cout << 
"\n\n--- " << name << 
"---" << endl;
 
   77     cout << 
"Current rotation: " << name << 
" - please see the image file for " 
   78                                             "desired axis and direction of " 
   80     cout << 
"Once you're ready, put your device in a level, forward-looking " 
   81             "orientation, then press enter." << endl;
 
   83     Eigen::Quaterniond initial;
 
   84     Eigen::Quaterniond current;
 
   86         ClientMainloopThread::lock_type lock(client.getMutex());
 
   87         initial = getOrientationState(iface);
 
   88         cout << 
"Initial axes:" << endl;
 
   89         cout << 
" - sensor X points " 
   90              << (initial * Eigen::Vector3d::UnitX()).transpose() << endl;
 
   91         cout << 
" - sensor Y points " 
   92              << (initial * Eigen::Vector3d::UnitY()).transpose() << endl;
 
   93         cout << 
" - sensor Z points " 
   94              << (initial * Eigen::Vector3d::UnitZ()).transpose() << endl;
 
   96         cout << 
"Now, please rotate the device as shown in the image. " << endl;
 
   97         cout << 
"Keep rotating";
 
  102             current = getOrientationState(iface);
 
  103             absRads = current.angularDistance(initial);
 
  104             int currentDots = (absRads / minAbsRadians) * totalDots;
 
  105             while (dots < currentDots) {
 
  109         } 
while (absRads < minAbsRadians);
 
  111     cout << 
"  OK!" << endl;
 
  112     auto relative = initial.conjugate() * current;
 
  113     auto angleAxis = Eigen::AngleAxisd(relative);
 
  114     cout << 
" - " << name << 
" - Rotated " << angleAxis.angle()
 
  115          << 
" radians about " << angleAxis.axis().transpose() << 
"\n" << endl;
 
  119 int main(
int argc, 
char *argv[]) {
 
  120     namespace po = boost::program_options;
 
  122     po::options_description desc(
"Options");
 
  124         (
"help", 
"produce help message")
 
  125         (
"route", po::value<std::string>()->default_value(
"/me/head"), 
"route to diagnose")
 
  126         (
"reset", 
"temporarily remove all transforms before performing diagnosis")
 
  130     po::variables_map vm;
 
  131     po::store(po::command_line_parser(argc, argv).options(desc).run(), vm);
 
  135     if (vm.count(
"help")) {
 
  136         cout << 
"Usage: diagnose-rotation [options]" << endl;
 
  137         cout << desc << 
"\n";
 
  142     std::string 
const dest = vm[
"route"].as<std::string>();
 
  144     bool resetTransform = (vm.count(
"reset") != 0);
 
  151         std::string origRouteString;
 
  152         if (resetTransform) {
 
  153             cout << 
"Running client mainloop briefly to get routes..." << endl;
 
  154             client.loopForDuration(boost::chrono::seconds(2));
 
  156             cout << 
"Removing any existing transforms..." << endl;
 
  157             Json::Value origRoute;
 
  159                 ctx.
get()->getRoutes().getRouteForDestination(dest);
 
  161             if (!reader.parse(origRouteString, origRoute)) {
 
  162                 cerr << 
"Error parsing existing route!" << endl;
 
  163                 cerr << origRouteString << endl;
 
  166             Json::Value origTransforms =
 
  167                 origRoute[osvr::common::routing_keys::source()];
 
  170                 origTransforms, [](Json::Value 
const &) { 
return true; });
 
  171             origRoute[osvr::common::routing_keys::source()] = cleanTransforms;
 
  174             cout << 
"Sent cleaned route: " << origRoute.toStyledString()
 
  177         cout << 
"Running thread and waiting a few seconds " 
  178                 "for startup..." << endl;
 
  180         boost::this_thread::sleep(SETTLE_TIME);
 
  182         auto pitch = getRotation(
"pitch", client, iface);
 
  183         auto yaw = getRotation(
"yaw", client, iface);
 
  184         auto roll = getRotation(
"roll", client, iface);
 
  186         cout << 
"Press enter to " 
  187              << (resetTransform ? 
"restore original transform and " : 
"")
 
  190         if (resetTransform) {
 
  191             cout << 
"Restoring original transform/route" << endl;
 
  194         boost::this_thread::sleep(SETTLE_TIME);
 
Interface handle object. Typically acquired from a ClientContext. 
Client context object: Create and keep one in your application. Handles lifetime management and provi...
void sendRoute(std::string const &route)
Sends a JSON route/transform object to the server. 
Header to bring unique_ptr into the osvr namespace. 
A structure defining a quaternion, often a unit quaternion representing 3D rotation. 
Interface getInterface(const std::string &path)
Get the interface associated with the given path. 
OSVR_ClientInterface get()
Get the raw OSVR_ClientInterface from this wrapper. 
#define OSVR_RETURN_SUCCESS
The "success" value for an OSVR_ReturnCode. 
OSVR_ClientContext get()
Gets the bare OSVR_ClientContext. 
Eigen::Quaterniond fromQuat(OSVR_Quaternion const &q)
Convert an OSVR_Quaternion to an Eigen::Quaterniond. 
Header for interoperation between the Eigen math library, the internal mini math library, and VRPN's quatlib. 
int main(int argc, char *argv[])
OSVR_ReturnCode osvrGetOrientationState(OSVR_ClientInterface iface, struct OSVR_TimeValue *timestamp, OSVR_OrientationState *state)
Get Orientation state from an interface, returning failure if none \ * exists. 
Standardized, portable parallel to struct timeval for representing both absolute times and time inter...