Skip to content

Pull Request for AHRS IO Processor #16

Merged
merged 16 commits into from May 11, 2020
23 changes: 23 additions & 0 deletions bfs/implementations/breadcrumbs/gen/AHRSInputIOProcessor.cpp
@@ -0,0 +1,23 @@

#include <iostream>

#include "DataSyncThread.hpp"
#include "AHRSInputIOProcessor.hpp"


int main()
{
IOProcessor* client = new AHRSInputIOProcessor;

if (!client->init())
{
while (client->loopCondition())
client->loop();

int result = client->close();
delete client;
return result;
}

return 0;
}
38 changes: 38 additions & 0 deletions bfs/implementations/breadcrumbs/include/AHRSInputIOProcessor.hpp
@@ -0,0 +1,38 @@
/*
*
* This is the IO Processor for the Xsens MTi-630 AHRS:
* https://www.xsens.com/products/mti-600-series
* The AHRS is able to calculate a lot of different orientational data,
* we are specfically using it to find the Yaw Euler Angle.
* Currently you must manually specify which COM port the device is connected
* to, this is right at the begining of the CreateFile() method call.
* By defualt it is set to COM8, you may have to change it to the correct port
* on your system. You can find the corrct port manually by opening Device Manager,
* under "Ports(COM & LPT)" you can see the ports detected by your system.
*/

#ifndef AHRS_INPUT_IO_PROCESSOR_HPP
#define AHRS_INPUT_IO_PROCESSOR_HPP

#include <windows.h>
#include <iostream>

#include "IOProcessor.hpp"
#include "DataSyncThread.hpp"
#include "Attribute.hpp"

class AHRSInputIOProcessor : public IOProcessor
{
public:
using IOProcessor::IOProcessor;

void loop();
bool loopCondition();
int configAHRS(); // Initialize the AHRS for the first time
private:
int iterations = 10;
bool configured = false;
HANDLE hSerial;
};

#endif
138 changes: 138 additions & 0 deletions bfs/implementations/breadcrumbs/io_procs/AHRSInputIOProcessor.cpp
@@ -0,0 +1,138 @@
#include "AHRSInputIOProcessor.hpp"


int AHRSInputIOProcessor::configAHRS()
{
DCB dcb = {0};
//HANDLE hSerial;

hSerial = CreateFile("COM8", // The COM port to connect to, may have to be changed
GENERIC_READ | GENERIC_WRITE, // depending on what COM port gets selected.
0,
0,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
0);

if (hSerial == INVALID_HANDLE_VALUE)
{
if(GetLastError() == ERROR_FILE_NOT_FOUND)
{
std::cout << "Serial port does not exist." << std::endl;
mfs16101 marked this conversation as resolved.
Show resolved Hide resolved
return 1; // serial port does not exist.
mfs16101 marked this conversation as resolved.
Show resolved Hide resolved
}
std::cout << "Some other error occurred." << std::endl;
return 2; // some other error occurred.
}

dcb.DCBlength = sizeof(dcb);

if (!GetCommState(hSerial, &dcb))
{
std::cout << "Error getting state." << std::endl;
return 3; // error getting state.
}

dcb.BaudRate = CBR_115200; // defualt baud rate of MT
dcb.ByteSize = 8;
dcb.StopBits = ONESTOPBIT;
dcb.Parity = NOPARITY;

if (!SetCommState(hSerial, &dcb))
{
std::cout << "Error setting serial port state." << std::endl;
return 4; // error setting serial port state
}

COMMTIMEOUTS timeouts = {0};

timeouts.ReadIntervalTimeout = 50;
timeouts.ReadTotalTimeoutConstant = 50;
timeouts.ReadTotalTimeoutMultiplier = 10;
timeouts.WriteTotalTimeoutConstant = 50;
timeouts.WriteTotalTimeoutMultiplier = 10;

if (!SetCommTimeouts(hSerial, &timeouts))
{
std::cout << "Error occured while setting timoemouts." << std::endl;
return 5;
}

std::cout << "Connection established!" << std::endl;
std::cout << "Setting up Config..." << std::endl;

unsigned char wBuff1[] = {0xFA,0xFF,0x30,0x00,0xD1}; // This is the GoToConfig message
DWORD dwBytesWritten = 0; // Number of bytes actually written

if (!WriteFile(hSerial, wBuff1, 6, &dwBytesWritten, NULL))
{
std::cout << "Error occured while trying to send GoToConfig message." << std::endl;
return 6;
}

unsigned char wBuff2[] = {0xFA,0xFF,0xC0,0x04,0x20,0x33,0x00,0x00,0xEA}; // This is the SetOutputConfiguration message
dwBytesWritten = 0;

if (!WriteFile(hSerial, wBuff2, 10, &dwBytesWritten, NULL))
{
std::cout << "Error occured while trying to send SetOutputConfiguration message." << std::endl;
return 7;
}

unsigned char wBuff3[] = {0xFA,0xFF,0x10,0x00,0xF1}; // This is the GoToMeasurment message
dwBytesWritten = 0;

if (!WriteFile(hSerial, wBuff3, 6, &dwBytesWritten, NULL))
{
std::cout << "Error occured while trying to send GoToMeasurment message." << std::endl;
return 8;
}

configured = true;
return 0;
}

bool AHRSInputIOProcessor::loopCondition()
{
return iterations > 0;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are still using this iterations variable for some reason.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have removed the iterations thing, but without it I don't know when to close the handle.

}

void AHRSInputIOProcessor::loop()
{
if (!configured)
configAHRS();

unsigned char szBuff[64 + 1] = {0}; // Buffer size
DWORD dwBytesRead = 0; // Number of bytes actually read

if (!ReadFile(hSerial, szBuff, 64, &dwBytesRead, NULL))
{
std::cout << "Error occured while trying to read bytes." << std::endl;
//return 9;
}

int index = -1;
for (int i=0; i < 32; i++) // This gets the bytes for the Yaw angle
{
if (szBuff[i] == 0xFA && szBuff[i+1] == 0xFF && szBuff[i+2] == 0x36)
{
index = i + 22;
break;
}
}

unsigned char yawArray[8];
if (index != -1) // This puts all those bytes
{
for (int i=0; i < 8; i++)
yawArray[i] = szBuff[index + (8-i)];
}

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need more than just the yaw angle. We need all of them!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The other angles don't change if we are only in a 2D plane, but I should be able to get the others also.

double doubleYaw = *reinterpret_cast<double * const>(yawArray);
Attribute attrib("yawAngle", 8, &doubleYaw);
getComms()->sendAttribute(attrib);
iterations--;

if (iterations == 0)
CloseHandle(hSerial);
}