OSVR Framework (Internal Development Docs)  0.6-1962-g59773924
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
DevicesWithParameters.cpp
Go to the documentation of this file.
1 
11 // Copyright 2014 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 "DevicesWithParameters.h"
27 #include "GetSerialPortState.h"
29 #ifdef OSVR_HAVE_USBSERIALENUM
31 #endif
33 #include "com_osvr_Multiserver_YEI_3Space_Sensor_json.h"
34 
35 // Library/third-party includes
36 #include <json/reader.h>
37 #include <json/value.h>
38 
39 #include <vrpn_YEI_3Space.h>
40 
41 // Standard includes
42 #include <vector>
43 #include <memory>
44 #include <string>
45 #include <string.h>
46 #include <utility>
47 
48 namespace {
51 class CStringArray : boost::noncopyable {
52  public:
53  typedef std::unique_ptr<char[]> UniqueCharArray;
54  void push_back(std::string const &str) {
55  // Remove null terminator from array
56  if (m_arrayHasNullTerminator()) {
57  m_data.pop_back();
58  }
59  {
60  const size_t stringLength = str.size() + 1;
61  UniqueCharArray copy(new char[stringLength]);
62  memcpy(copy.get(), str.c_str(), stringLength);
63  m_dataOwnership.push_back(std::move(copy));
64  }
65  m_data.push_back(m_dataOwnership.back().get());
66  }
67  const char **get_array() {
68  // Ensure null terminator on array
69  if (!m_arrayHasNullTerminator()) {
70  m_data.push_back(nullptr);
71  }
72  return m_data.data();
73  }
74 
75  private:
76  bool m_arrayHasNullTerminator() const {
77  return !m_data.empty() && nullptr == m_data.back();
78  }
79  std::vector<const char *> m_data;
80  std::vector<UniqueCharArray> m_dataOwnership;
81 };
82 } // namespace
83 
84 static void createYEIImpl(VRPNMultiserverData &data, OSVR_PluginRegContext ctx,
85  Json::Value const &root, std::string port) {
86  if (port.empty()) {
87  throw std::runtime_error(
88  "Could not create a YEI device: no port specified!.");
89  }
90  port = normalizeAndVerifySerialPort(port);
91 
92  bool calibrate_gyros_on_setup =
93  root.get("calibrateGyrosOnSetup", false).asBool();
94  bool tare_on_setup = root.get("tareOnSetup", false).asBool();
95  double frames_per_second = root.get("framesPerSecond", 250).asFloat();
96 
97  Json::Value commands = root.get("resetCommands", Json::arrayValue);
98  CStringArray reset_commands;
99 
100  if (commands.empty()) {
101  // Enable Q-COMP filtering by default
102  reset_commands.push_back("123,2");
103  } else {
104  for (Json::ArrayIndex i = 0, e = commands.size(); i < e; ++i) {
105  reset_commands.push_back(commands[i].asString());
106  }
107  }
108 
110 
111  reg.registerDevice(new vrpn_YEI_3Space_Sensor(
112  reg.useDecoratedName(data.getName("YEI_3Space_Sensor")).c_str(),
113  reg.getVRPNConnection(), port.c_str(), 115200, calibrate_gyros_on_setup,
114  tare_on_setup, frames_per_second, 0, 0, 1, 0,
115  reset_commands.get_array()));
116  reg.setDeviceDescriptor(
117  osvr::util::makeString(com_osvr_Multiserver_YEI_3Space_Sensor_json));
118 }
119 
120 void createYEI(VRPNMultiserverData &data, OSVR_PluginRegContext ctx,
121  const char *params) {
122  Json::Reader reader;
123  Json::Value root;
124  if (!reader.parse(params, root)) {
125  throw std::runtime_error("Could not parse configuration: " +
126  reader.getFormattedErrorMessages());
127  }
128  auto port = root.get("port", "").asString();
129 #ifdef OSVR_HAVE_USBSERIALENUM
130  // Have usb serial enum: specifying a port means you just want that one,
131  // not specifying means you want it to auto-configure all.
132  if (!port.empty()) {
133  createYEIImpl(data, ctx, root, port);
134  } else {
135  static const uint16_t vID = 0x2476;
136  static const uint16_t pID = 0x1010;
137  for (auto &&dev : osvr::usbserial::enumerate(vID, pID)) {
138  createYEIImpl(data, ctx, root, dev.getPort());
139  }
140  }
141 #else // !OSVR_HAVE_USBSERIALENUM
142  // No usb serial enum: must unconditionally specify a port.
143  createYEIImpl(data, ctx, root, port);
144 #endif // OSVR_HAVE_USBSERIALENUM
145 }
std::string makeString(const char(&arrayLiteral)[N])
Safely and easily convert a literal array of characters (like from osvr_json_to_c) into a std::string...
Header with a convenience function to make a std::string out of a non-null-terminated char array (str...
OSVR_EXTERN_C_BEGIN typedef void * OSVR_PluginRegContext
A context pointer passed in to your plugin's entry point and other locations of control flow transfer...
std::string normalizeAndVerifySerialPort(std::string const &port)
Normalizes and verifies the accessibility of a serial port and throws a std::exception unless it is a...