LORD-MicroStrain / MSCL

MicroStrain Communication Library
https://www.microstrain.com/software/mscl
MIT License
76 stars 57 forks source link

How can I write / read the MIP stream to a binary file, but still leverage MSCL's parsing? #365

Open sebuck opened 10 months ago

sebuck commented 10 months ago

I'm using MSCL and an IntertialNode to read and PARSE my 3DM-GQ7's messages. For future processing, I also need to both write and read the raw binary stream to disk. I'm hoping to continue to leverage MSCL's parsing and to not write my own parser.

  1. How do I write the stream to a binary file and still leverage MSCL's MIP message parsing? The documentation for Connection::rawByteMode says that it stops the data from being parsed. Is using debugMode(true) and getDebugData the answer or is there a better solution?
  2. How do I read my binary file and leverage MSCL's MIP message parsing? MSCL obviously doesn't have any file functionality. Is there a way to use something similar to ByteStream, fill it with my file contents, and pass it to a Connection / InterialNode?
msclissa commented 10 months ago
  1. Yes, enabling debugMode and using getDebugData on the connection object allows you to get the raw data (read and write) while MSCL still executes MIP parsing on data in.
  2. Unfortunately we never got around to implementing a "connectionless" Connection class that would allow data to be easily read in from a file and passed into the Connection object's MIP parser. A couple options here:
    • Set up a TCP port that MSCL can connect to and pass data from the binary through that port. Note: I have not personally tried this, but can't think of a reason it wouldn't work for data parsing.
    • If you're using C++ you might consider switching over to our MIP SDK. This is a new API in development specifically for our inertial product line - at this point both the MIP SDK and MSCL are being maintained alongside one another but eventually we will be shifting support and focus to the MIP SDK. The MIP parser in the MIP SDK is also not tied to the Connection structure - feeding in data read from a binary file would be fairly straightforward. If you'd like to try to switch over we'd be happy to help get you up and running with it. MIP SDK example code for GQ7 can be found here.

Simple Record to Binary Example This example enables debug mode on the Connection object, opens a file, and writes all data read from the connection to that file, with the option to also include data written to the connection in the binary file. Keep in mind including written data can end up interrupting read data resulting in incomplete data packets when reading back the binary file.

#pragma once
#include "mscl/mscl.h"

using namespace std;

void recordRawBinaryData(mscl::InertialNode& node)
{
    // set message format to support channels to ensure all data required for full analysis is included
    // if commmented, message format will not be set/overwritten
    //node.setFactoryStreamingChannels(mscl::InertialTypes::FactoryStreamingOption::FACTORY_STREAMING_OVERWRITE);

    // enable debug mode so MSCL will collect raw byte info
    node.connection().debugMode(true);

    // setup file information
    ofstream binFile;
    string filepath = "";
    binFile.open(filepath.c_str(), std::ios::out | std::ios::binary);

    // listen and record continuously
    while (true)
    {
        // get raw binary data over the connection
        mscl::ConnectionDebugDataVec data = node.connection().getDebugData(1000);

        // loop through data
        for (auto i : data)
        {
            //cout << endl;
            if (i.fromRead())
            {
                //cout << "Read  (" << i.timestamp().str() << ")" << endl;
            }
            else
            {
                //cout << "Write  (" << i.timestamp().str() << ")" << endl;

                // comment out 'continue' to include commands/packets sent to the device in the binary file
                // with 'continue' uncommented, only data, command responses, packets fread from the device will be recorded
                continue;
            }

            // loop through each byte of data
            for (auto byte : i.data())
            {
                // write data byte to file
                binFile.write((char*)&byte, sizeof(uint8_t));

                //cout << setfill('0') << setw(2) << hex << static_cast<unsigned short>(byte);// << " ";
            }

            //cout << endl;
        }
    }

    // close file
    binFile.close();
}
sebuck commented 10 months ago

Thank you for your quick response! Yes, I do see how the MIP SDK is more flexible and can support reading (and writing). Unfortunately, we currently can't use the C++ MIP SDK. However, we will eventually need to create tools to read and parse our binary files which should be able to leverage the MIP SDK.