Display problems are tough because there's so many possible issues to work through, but tracker issues are pretty easy to troubleshoot, at least to the extent of proving to yourself your hardware is being detected and sending data.
The head tracker is simply a solid state accelerometer, gyroscope and magnetometer. This is now common hardware, having also been driven by the mobile computing market, as well as have been driven by the same mobile market as well as the game controller market.
Applications tend to get data out of a sensor fusion object, which adds features like turning a continuous stream of tracker messages into a cohesive orientation in the form of a quaternion. Sensor fusion also adds magnetic calibration for yaw correction and prediction based on the current speed of movement. These things can be enabled and disabled, so it's sometimes not clear whether you have a problem with your sensor fusion setup, or the connection to the SDK, or the hardware itself.
The easiest way to troubleshoot these issues is to make a minimal application that will read the tracker messages and output something to the console, bypassing sensor fusion completely. Once you're assured that's working you can start building up from there.
using namespace std;
using namespace OVR;
class TrackerHandler : public MessageHandler {
public:
virtual void OnMessage(const Message& msg) {
const MessageBodyFrame & trackerMessage = *(MessageBodyFrame*) &msg;
const Vector3f & accel = trackerMessage.Acceleration;
cout << accel.x << " " << accel.y << " " << accel.z << " " << accel.Length() << endl;
}
virtual bool SupportsMessageType(MessageType type) const {
return Message_BodyFrame == type;
}
};
class Example2 {
public:
Ptr pSensor;
Ptr pManager;
Example2() {
System::Init();
pManager = *DeviceManager::Create();
if (!pManager) {
throw std::exception();
}
pSensor = *pManager->EnumerateDevices().CreateDevice();
if (!pSensor) {
throw std::exception();
}
}
virtual ~Example2() {
if (pSensor) {
pSensor->SetMessageHandler(0);
pSensor.Clear();
}
if (pManager) {
pManager.Clear();
}
System::Destroy();
}
};
int main(int argc, char ** argv) {
Example2 example;
TrackerHandler handler;
example.pSensor->SetMessageHandler(&handler);
// Sleep and let the tracker handler receive messages, which will
// be processed in another thread
usleep(1000 * 1000 * 10);
return 0;
}
If that gives you output, you can follow it up by trying sensor fusion instead, as shown here:
int main(int argc, char ** argv) {
Example2 example;
SensorFusion fusion;
if (!fusion.AttachToSensor(example.pSensor)) {
throw std::exception();
}
for (int i = 0; i < 10; ++i) {
Quatf orientation = fusion.GetOrientation();
cout << orientation.x << " " << orientation.y << " " << orientation.z << " " << orientation.w << endl;
usleep(1000 * 1000);
}
return;
}
You may need to replace the declaration of usleep with something from your platform if you're not working in Linux. Remember to change the value from microseconds to seconds or milliseconds if appropriate.
Could this be used to record from the accelerometer, magnetometer, and gyroscope?
ReplyDelete