ovasCDriverOpenBCI.h 6.4 KB
Newer Older
1 2 3 4
/*
 * OpenBCI driver for OpenViBE
 *
 * \author Jeremy Frey
5
 * \author Yann Renard
6 7
 *
 */
jfrey's avatar
jfrey committed
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
#ifndef __OpenViBE_AcquisitionServer_CDriverOpenBCI_H__
#define __OpenViBE_AcquisitionServer_CDriverOpenBCI_H__

#include "ovasIDriver.h"
#include "../ovasCHeader.h"

#include "../ovasCSettingsHelper.h"
#include "../ovasCSettingsHelperOperators.h"

#if defined TARGET_OS_Windows
 typedef void * FD_TYPE;
#elif defined TARGET_OS_Linux
 typedef OpenViBE::int32 FD_TYPE;
#else
#endif

#include <vector>
25 26
#include <deque>

jfrey's avatar
jfrey committed
27 28
namespace OpenViBEAcquisitionServer
{
29 30 31
	/**
	 * \class CDriverOpenBCI
	 * \author Jeremy Frey
32
	 * \author Yann Renard
33
	 */
jfrey's avatar
jfrey committed
34 35 36 37 38 39 40 41
	class CDriverOpenBCI : public OpenViBEAcquisitionServer::IDriver
	{
	public:

		CDriverOpenBCI(OpenViBEAcquisitionServer::IDriverContext& rDriverContext);
		virtual void release(void);
		virtual const char* getName(void);

42
		virtual OpenViBE::boolean initialize(const OpenViBE::uint32 ui32SampleCountPerSentBlock, OpenViBEAcquisitionServer::IDriverCallback& rCallback);
jfrey's avatar
jfrey committed
43 44 45 46 47 48 49 50 51
		virtual OpenViBE::boolean uninitialize(void);

		virtual OpenViBE::boolean start(void);
		virtual OpenViBE::boolean stop(void);
		virtual OpenViBE::boolean loop(void);

		virtual OpenViBE::boolean isConfigurable(void);
		virtual OpenViBE::boolean configure(void);
		virtual const OpenViBEAcquisitionServer::IHeader* getHeader(void) { return &m_oHeader; }
52 53 54 55

	public:

		typedef enum
jfrey's avatar
jfrey committed
56
		{
57 58 59 60 61 62
			ParserAutomaton_Default,
			ParserAutomaton_StartByteReceived,
			ParserAutomaton_SampleNumberReceived,
			ParserAutomaton_EEGSamplesReceived,
			ParserAutomaton_AccelerometerSamplesReceived,
		} EParserAutomaton;
jfrey's avatar
jfrey committed
63 64 65

	protected:

66 67
		OpenViBE::int32 interpret24bitAsInt32(const std::vector < OpenViBE::uint8 >& byteBuffer);
		OpenViBE::int32 interpret16bitAsInt32(const std::vector < OpenViBE::uint8 >& byteBuffer);
68
		OpenViBE::int16 parseByte(OpenViBE::uint8 ui8Actbyte);
69 70 71

		OpenViBE::boolean sendCommand(::FD_TYPE i32FileDescriptor, const char *sCommand, OpenViBE::boolean bWaitForResponse, OpenViBE::boolean bLogResponse, OpenViBE::uint32 ui32Timeout, std::string& sReply);
		OpenViBE::boolean resetBoard(::FD_TYPE i32FileDescriptor, bool bRegularInitialization);
72
		OpenViBE::boolean handleCurrentSample(OpenViBE::int32 packetNumber); // will take car of samples fetch from OpenBCI board, dropping/merging packets if necessary
73 74 75 76 77 78 79 80 81
		void updateDaisy(OpenViBE::boolean bQuietLogging); // update internal state regarding daisy module

	protected:

		OpenViBE::boolean openDevice(::FD_TYPE * pFileDescriptor, OpenViBE::uint32 ui32TtyNumber);
		void closeDevice(::FD_TYPE i32FileDescriptor);
		OpenViBE::uint32 writeToDevice(::FD_TYPE i32FileDescriptor, const void* pBuffer, const OpenViBE::uint32 ui32BufferSize);
		OpenViBE::uint32 readFromDevice(::FD_TYPE i32FileDescriptor, void* pBuffer, const OpenViBE::uint32 ui32BufferSize, const OpenViBE::uint64 ui64TimeOut=0);

jfrey's avatar
jfrey committed
82 83 84 85 86 87 88
	protected:

		SettingsHelper m_oSettings;

		OpenViBEAcquisitionServer::IDriverCallback* m_pCallback;
		OpenViBEAcquisitionServer::CHeader m_oHeader;

89 90 91 92 93
		::FD_TYPE  m_i32FileDescriptor;

		OpenViBE::CString m_sDriverName;
		OpenViBE::CString m_sTTYName;
		OpenViBE::CString m_sAdditionalCommands; // string to send possibly upon initialisation
jfrey's avatar
jfrey committed
94 95
		OpenViBE::uint32 m_ui32ChannelCount;
		OpenViBE::uint32 m_ui32DeviceIdentifier;
96 97
		OpenViBE::uint32 m_ui32ReadBoardReplyTimeout; // parameter com init string
		OpenViBE::uint32 m_ui32FlushBoardReplyTimeout;  // parameter com init string
98
		OpenViBE::boolean m_bDaisyModule; // daisy module attached or not
jfrey's avatar
jfrey committed
99

100 101
		// OpenBCI protocol related
		OpenViBE::int16 m_i16SampleNumber; // returned by the board
102
		OpenViBE::uint32 m_ui32ReadState; // position in the sample (see doc)
103
		OpenViBE::uint8 m_ui8SampleBufferPosition;// position in the buffer
104
		std::vector < OpenViBE::uint8 > m_vEEGValueBuffer; // buffer for one EEG value (int24)
105
		std::vector < OpenViBE::uint8 > m_vAccValueBuffer; // buffer for one accelerometer value (int16)
106
		const static OpenViBE::uint8 EEGValueBufferSize = 3; // int24 == 3 bytes
107
		const static OpenViBE::uint8 AccValueBufferSize = 2; // int16 == 2 bytes
108 109
		const static OpenViBE::uint8 EEGValueCountPerSample = 8; // the board send EEG values 8 by 8 (will concatenate 2 samples with daisy module)
		const static OpenViBE::uint8 AccValueCountPerSample = 3; // 3 accelerometer data per sample
jfrey's avatar
jfrey committed
110

111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
		OpenViBE::uint32 MissingSampleDelayBeforeReset; // in ms - value acquired from configuration manager
		OpenViBE::uint32 DroppedSampleCountBeforeReset; // in samples - value acquired from configuration manager
		OpenViBE::uint32 DroppedSampleSafetyDelayBeforeReset; // in ms - value acquired from configuration manager

		std::deque < OpenViBE::uint32 > m_vDroppedSampleTime;

		OpenViBE::float32 m_f32UnitsToMicroVolts; // convert from int32 to microvolt
		OpenViBE::float32 m_f32UnitsToRadians; // converts from int16 to radians
		OpenViBE::uint32 m_ui32ExtractPosition; // used to situate sample reading both with EEG and accelerometer data
		OpenViBE::uint32 m_ui32ValidAccelerometerCount;
		OpenViBE::int32  m_i32LastPacketNumber; // used to detect consecutive packets when daisy module is used

		// buffer for multibyte reading over serial connection
		std::vector < OpenViBE::uint8 > m_vReadBuffer;
		// buffer to store sample coming from OpenBCI -- filled by parseByte(), passed to handleCurrentSample()
jfrey's avatar
jfrey committed
126
		std::vector < OpenViBE::float32 > m_vSampleEEGBuffer;
127
		std::vector < OpenViBE::float32 > m_vSampleEEGBufferDaisy;
jfrey's avatar
jfrey committed
128
		std::vector < OpenViBE::float32 > m_vSampleAccBuffer;
129 130 131 132 133 134
		std::vector < OpenViBE::float32 > m_vSampleAccBufferTemp;

		// buffer to store aggregated samples
		std::vector < std::vector < OpenViBE::float32 > > m_vChannelBuffer; // buffer to store channels & chunks
		std::vector < OpenViBE::float32 > m_vSampleBuffer;

135
		bool m_bSeenPacketFooter; // extra precaution to sync packets
jfrey's avatar
jfrey committed
136

137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
		// mechanism to call resetBoard() if no data are received
		OpenViBE::uint32 m_ui32Tick; // last tick for polling
		OpenViBE::uint32 m_ui32StartTime; // actual time since connection

		// sample storing for device callback and serial i/o
		std::vector < OpenViBE::float32 > m_vCallbackSample;

	private:

		typedef struct
		{
			OpenViBE::uint32 ui32DeviceVersion;
			OpenViBE::uint32 ui32DeviceChannelCount;

			OpenViBE::uint32 ui32BoardId;
			OpenViBE::uint32 ui32DaisyId;
			OpenViBE::uint32 ui32MocapId;

			char sBoardChipset[64];
			char sDaisyChipset[64];
			char sMocapChipset[64];
		} SDeviceInformation;

		SDeviceInformation m_oDeviceInformation;
jfrey's avatar
jfrey committed
161 162 163 164
	};
};

#endif // __OpenViBE_AcquisitionServer_CDriverOpenBCI_H__