25 #ifndef INCLUDED_MakeHDKTrackingSystem_h_GUID_B7C07A08_2BF8_45B2_4545_39979BA637E5
26 #define INCLUDED_MakeHDKTrackingSystem_h_GUID_B7C07A08_2BF8_45B2_4545_39979BA637E5
48 #undef OSVR_UVBI_DISABLE_AUTOCALIB
49 #undef OSVR_UVBI_DEBUG_EMISSION_DIRECTION
50 #undef DEBUG_REAR_BEACON_TRANSFORM
59 static const std::vector<std::string>
60 OsvrHdkLedIdentifier_SENSOR0_PATTERNS = {
99 static const std::vector<std::string>
100 OsvrHdkLedIdentifier_SENSOR1_PATTERNS = {
108 static const auto SCALE_FACTOR = std::milli::den;
110 template <
typename Scalar>
using cvMatx33 = cv::Matx<Scalar, 3, 3>;
113 template <
typename Scalar>
inline cvMatx33<Scalar> get180AboutY() {
114 auto ret = cvMatx33<Scalar>::eye();
123 template <
typename Scalar>
inline cvMatx33<Scalar> getTransform() {
127 return get180AboutY<Scalar>();
131 template <
typename Scalar>
132 inline cvMatx33<Scalar> getTransformAndScale() {
133 return getTransform<Scalar>() * (
Scalar(1) /
Scalar(SCALE_FACTOR));
137 template <
typename Scalar>
138 inline cv::Point3_<Scalar>
139 transformFromHDKData(cv::Point3_<Scalar> input) {
140 static const cvMatx33<Scalar> xformMatrix =
141 getTransformAndScale<Scalar>();
142 return xformMatrix * input;
146 template <
typename Scalar>
147 inline cv::Vec<Scalar, 3>
148 transformFromHDKData(cv::Vec<Scalar, 3> input) {
149 static const cvMatx33<Scalar> xformMatrix = getTransform<Scalar>();
150 return xformMatrix * input;
153 inline LocationPoint rotatePoint180AboutY(LocationPoint pt) {
161 inline bool tryLoadingCalibration(std::string
const &filename,
162 TargetSetupData &data) {
167 auto calibratedLocations = tryLoadingArrayOfPointsFromFile(filename);
169 auto n = calibratedLocations.size();
170 const auto numFrontBeacons = getNumHDKFrontPanelBeacons();
171 const auto numRearBeacons = getNumHDKRearPanelBeacons();
174 if (n == numFrontBeacons || n == (numFrontBeacons + numRearBeacons)) {
178 calibratedLocations.resize(numFrontBeacons);
180 calibratedLocations, begin(data.locations),
181 [](LocationPoint pt) { return transformFromHDKData(pt); });
184 for (std::size_t i = 0; i < numFrontBeacons; ++i) {
185 data.initialAutocalibrationErrors[i] *=
186 BEACON_AUTOCALIB_ERROR_SCALE_IF_CALIBRATED;
193 inline Point3Vector
const &getTarget0Locations(BuiltInTargetSets target) {
195 case BuiltInTargetSets::HDK1xChassis:
196 return OsvrHdkLedLocations_SENSOR0;
198 case BuiltInTargetSets::HDK2Chassis:
199 return OsvrHdk2LedLocations_SENSOR0;
204 inline Point3Vector
const &getTarget1Locations(BuiltInTargetSets target) {
206 case BuiltInTargetSets::HDK1xChassis:
207 return OsvrHdkLedLocations_SENSOR1;
209 case BuiltInTargetSets::HDK2Chassis:
210 return OsvrHdk2LedLocations_SENSOR1;
215 inline std::unique_ptr<TrackingSystem>
216 makeHDKTrackingSystem(ConfigParams
const ¶ms) {
217 auto silent = params.silent;
219 std::unique_ptr<TrackingSystem> sys(
new TrackingSystem(params));
220 #ifdef OSVR_UVBI_DEBUG_EMISSION_DIRECTION
222 auto xform = getTransform<float>();
223 std::cout <<
"Transform matrix:\n" << xform << std::endl;
226 auto sampleBeacons = {5, 32, 9, 10};
229 auto hmd = sys->createTrackedBody();
231 throw std::runtime_error(
232 "Could not create a tracked body for the HMD!");
235 const auto numFrontBeacons = getNumHDKFrontPanelBeacons();
236 const auto numRearBeacons = getNumHDKRearPanelBeacons();
237 const auto useRear = params.includeRearPanel;
238 const auto numBeacons =
239 numFrontBeacons + (useRear ? numRearBeacons : 0);
242 TargetSetupData data;
243 data.setBeaconCount(numBeacons, BaseMeasurementVariance,
244 params.initialBeaconError);
247 data.patterns = OsvrHdkLedIdentifier_SENSOR0_PATTERNS;
251 data.patterns.insert(end(data.patterns),
252 begin(OsvrHdkLedIdentifier_SENSOR1_PATTERNS),
253 end(OsvrHdkLedIdentifier_SENSOR1_PATTERNS));
258 auto locationsEnd = range_transform(
259 getTarget0Locations(params.targetSet), begin(data.locations),
260 [](LocationPoint pt) { return transformFromHDKData(pt); });
263 if (!params.calibrationFile.empty()) {
264 auto success = tryLoadingCalibration(params.calibrationFile, data);
267 messages::loadedCalibFileSuccessfully(
268 params.calibrationFile);
278 const auto distanceBetweenPanels = computeDistanceBetweenPanels(
279 params.headCircumference,
280 params.headToFrontBeaconOriginDistance);
283 auto transformBackPoints =
284 [distanceBetweenPanels](LocationPoint pt) {
285 auto p = rotatePoint180AboutY(pt) -
286 LocationPoint(0, 0, distanceBetweenPanels);
287 return transformFromHDKData(p);
289 range_transform(getTarget1Locations(params.targetSet), locationsEnd,
290 transformBackPoints);
291 #ifdef DEBUG_REAR_BEACON_TRANSFORM
292 std::cout <<
"Front beacon position (id 32): "
293 << data.locations[32 - 1] <<
" (originally "
294 << OsvrHdkLedLocations_SENSOR0[32 - 1] <<
")"
296 std::cout <<
"Back beacon position (id 40): "
297 << data.locations[40 - 1] <<
" (originally "
298 << OsvrHdkLedLocations_SENSOR1.back() <<
")" << std::endl;
304 OsvrHdkLedDirections_SENSOR0, begin(data.emissionDirections),
305 [](EmissionDirectionVec v) { return transformFromHDKData(v); });
310 data.emissionDirections.resize(numFrontBeacons);
311 data.emissionDirections.resize(
313 transformFromHDKData(EmissionDirectionVec(0, 0, -1)));
315 #ifdef OSVR_UVBI_DEBUG_EMISSION_DIRECTION
316 for (
auto &beaconOneBased : sampleBeacons) {
317 std::cout <<
"Beacon ID " << beaconOneBased
318 <<
" emission direction "
319 << data.emissionDirections[beaconOneBased - 1]
324 #ifdef OSVR_UVBI_DISABLE_AUTOCALIB
325 for (decltype(numBeacons) i = 0; i < numBeacons; ++i) {
327 data.markBeaconFixed(makeOneBased(ZeroBasedBeaconId(i)));
330 for (
auto idx : {16, 17, 19, 20}) {
333 data.markBeaconFixed(OneBasedBeaconId(idx));
339 std::copy(begin(OsvrHdkLedVariances_SENSOR0),
340 end(OsvrHdkLedVariances_SENSOR0),
341 begin(data.baseMeasurementVariances));
345 if (params.targetSet == BuiltInTargetSets::HDK2Chassis) {
346 for (
auto id : getOneBasedIDsOfMissingBeaconsHDK2()) {
347 data.markBeaconInactive(OneBasedBeaconId(
id));
352 auto summary = data.cleanAndValidate(params.silent);
354 auto opticalTarget = hmd->createTarget(
356 Eigen::Vector3d(0, 0, 0.04141),
358 Eigen::Vector3d::Zero(),
362 if (!opticalTarget) {
363 throw std::runtime_error(
364 "Could not create a tracked target for the HMD!");
368 !params.imu.path.empty() &&
369 (params.imu.useAngularVelocity || params.imu.useOrientation ||
370 params.imu.calibrateAnyway);
373 hmd->createIntegratedIMU(params.imu.orientationVariance,
374 params.imu.angularVelocityVariance);
376 throw std::runtime_error(
"Could not create an integrated "
377 "IMU object for the HMD!");
382 sys->setCameraPose(Eigen::Isometry3d(Eigen::Translation3d(
383 Eigen::Vector3d::Map(params.cameraPosition))));
390 #endif // INCLUDED_MakeHDKTrackingSystem_h_GUID_B7C07A08_2BF8_45B2_4545_39979BA637E5
double Scalar
Common scalar type.