VectorNav C++ Library
ez_async_data/main.cpp

This example illustrates using the high-level EzAsyncData class to access a easily connect to a VectorNav sensor on a system with an operating system and display current data from the VectorNav sensor.

Visual Studio (Windows)

  1. Open the solution file for your specific Visual Studio version located at <root>/cpp/examples/ez_async_data/projects/vs20XX/ez_async_data.sln.
  2. Open the project file main.cpp and edit the SensorPort and SensorBaudrate constants at the top of the main() function to the settings used by your attached VectorNav sensor.
  3. Build the entire solution by going to the menu BUILD -> Build Solution.
  4. Right-click the project ez_async_data and select Debug -> Start new instance.

Make (Linux/Mac OS X)

  1. You will first need to open the file <root>/cpp/examples/ez_async_data/main.cpp and edit the SensorPort and SensorBaudrate constants at the top of the main() function to the settings used by your attached VectorNav sensor.
  2. Open a terminal and change to the directory <root>/cpp/examples/ez_async_data .
  3. To build the example, run the command make .
  4. Run the example by executing the command sudo ./ez_async_data . Note that it is required to run the command using sudo since administrator privileges are required to access the serial ports on Linux.

CLion (Windows/Linux/Mac OS X)

  1. Open the project file located at <root>/cpp/examples/ez_async_data in CLion.
  2. Open the project file main.cpp and edit the SensorPort and SensorBaudrate constants at the top of the main() function to the settings used by your attached VectorNav sensor.
  3. Make sure the ez_async_data configuration is active. You can set this by clicking the small drop-down list in the upper-right corner and selecting the option ez_async_data.
  4. Build the solution by going to the menu Run -> Build.
  5. Run the example by going to the menu Run -> Run 'gettings_started'.

Other

To compile and run for an environment not listed here, you will need to add all of the *.c files in the directory <root>/c/src along with the file located at <root>/c/examples/ez_async_data/main.c to your project for compilation. You will also need to add <root>/c/include to your include directories. Finally, before compiling, open the file main.cpp and edit the SensorPort and SensorBaudrate constants at the top of the main() function to the settings used by your attached VectorNav sensor.

#include <iostream>
// Include this header file to get access to the EzAsyncData class.
#include "vn/ezasyncdata.h"
// We need this file for our sleep function.
#include "vn/thread.h"
using namespace std;
using namespace vn::math;
using namespace vn::sensors;
using namespace vn::protocol::uart;
using namespace vn::xplat;
int main(int argc, char *argv[])
{
// This example walks through using the EzAsyncData class to easily access
// asynchronous data from a VectorNav sensor at a slight performance hit which is
// acceptable for many applications, especially simple data logging.
// First determine which COM port your sensor is attached to and update the
// constant below. Also, if you have changed your sensor from the factory
// default baudrate of 115200, you will need to update the baudrate
// constant below as well.
const string SensorPort = "COM1"; // Windows format for physical and virtual (USB) serial port.
// const string SensorPort = "/dev/ttyS1"; // Linux format for physical serial port.
// const string SensorPort = "/dev/ttyUSB0"; // Linux format for virtual (USB) serial port.
// const string SensorPort = "/dev/tty.usbserial-FTXXXXXX"; // Mac OS X format for virtual (USB) serial port.
// const string SensorPort = "/dev/ttyS0"; // CYGWIN format. Usually the Windows COM port number minus 1. This would connect to COM1.
const uint32_t SensorBaudrate = 115200;
// We create and connect to a sensor by the call below.
EzAsyncData* ez = EzAsyncData::connect(SensorPort, SensorBaudrate);
// Now let's display the latest yaw, pitch, roll data at 5 Hz for 5 seconds.
for (int i = 0; i < 25; i++)
{
Thread::sleepMs(200);
// This reads the latest data that has been processed by the EzAsyncData class.
// Make sure that we have some yaw, pitch, roll data.
if (!cd.hasYawPitchRoll())
cout << "YPR Unavailable." << endl;
else
cout << "Current YPR: " << cd.yawPitchRoll() << endl;
}
// Most of the asynchronous data handling is done by EzAsyncData but there are times
// when we wish to configure the sensor directly while still having EzAsyncData do
// most of the grunt work.This is easily accomplished and we show changing the ASCII
// asynchronous data output type here.
try
{
}
catch (...)
{
cout << "Error setting async data output type." << endl;
return -1;
}
cout << "[New ASCII Async Output]" << endl;
// We can now display yaw, pitch, roll data from the new ASCII asynchronous data type.
for (int i = 0; i < 25; i++)
{
Thread::sleepMs(200);
if (!cd.hasYawPitchRoll())
cout << "YPR Unavailable." << endl;
else
cout << "Current YPR: " << cd.yawPitchRoll() << endl;
}
// The CompositeData structure contains some helper methods for getting data
// into various formats. For example, although the sensor is configured to
// output yaw, pitch, roll, our application might need it as a quaternion
// value. However, if we query the quaternion field, we see that we don't
// have any data.
cout << "HasQuaternion: " << ez->currentData().hasQuaternion() << endl;
// Uncommenting the line below will cause an exception to be thrown since
// quaternion data is not available.
// cout << "Current Quaternion: " << ez->currentData().quaternion() << endl;
// However, the CompositeData structure provides the anyAttitude field
// which will perform the necessary conversions automatically.
cout << "[Quaternion from AnyAttitude]" << endl;
for (int i = 0; i < 25; i++)
{
Thread::sleepMs(200);
// This reads the latest data that has been processed by the EzAsyncData class.
// Make sure that we have some attitude data.
if (!cd.hasAnyAttitude())
cout << "Attitude Unavailable." << endl;
else
cout << "Current Quaternion: " << cd.anyAttitude().quat() << endl;
}
// Throughout this example, we have been using the ez->currentData() to get the most
// up-to-date readings from the sensor that have been processed. When called, this
// method returns immediately with the current values, thus the reason we have to
// put the Thread::sleepMs(200) in the for loop. Otherwise, we would blaze through
// the for loop and just print out the same values. The for loop below illustrates
// this.
cout << "[For Loop Without Sleep]" << endl;
for (int i = 0; i < 25; i++)
{
if (!cd.hasYawPitchRoll())
cout << "YPR Unavailable." << endl;
else
cout << "Current YPR: " << cd.yawPitchRoll() << endl;
}
// Often, we would like to get and process each packet received from the sensor.
// This is not realistic with ez->currentData() since it is non-blocking and we
// would also have to compare each CompositeData struture for changes in the data.
// However, EzAsyncData also provides the getNextData() method which blocks until
// a new data packet is available. The for loop below shows how to output each
// data packet received from the sensor using getNextData().
cout << "[getNextData Method]" << endl;
for (int i = 0; i < 25; i++)
{
if (!cd.hasYawPitchRoll())
cout << "YPR Unavailable." << endl;
else
cout << "Current YPR: " << cd.yawPitchRoll() << endl;
}
ez->disconnect();
delete ez;
return 0;
}