跳转至

gForce SDK 手册


获取数据的函数

SDK 类型 方位数据 姿态数据 设备状态 Other Data* Data Config Function
gForceCXX onOrientationData(...)** onGestureData(...)** onDeviceStatusChanged(...)** onExtendedDeviceData(...)** DeviceSetting::setDataNotifSwitch(...)
gForceCSharp onOrientationData(...)** onGestureData(...)** onDeviceStatusChanged(...)** onExtendedDeviceData(...)** Device::setDataSwitch(...)
gForcePython Callback of GF.startDataNotification(...) Callback of GF.startDataNotification(...) Callback of GF.startDataNotification(...) Callback of GF.startDataNotification(...) GF.setDataNotifSwitch(...)
gForceArduino GForceAdapter::GetGForceData(...) GForceAdapter::GetGForceData(...) GForceAdapter::GetGForceData(...) GForceAdapter::GetGForceData(...)*** NA
gForceEmbedded GForceAdapter::GetGForceData(...) GForceAdapter::GetGForceData(...) GForceAdapter::GetGForceData(...) GForceAdapter::GetGForceData(...)*** NA

注意:

* : 包含10种数据类型

** : 在HubListener的子类中

*** : 仅支持EMG数据


回调中的数据格式

当所需的数据通知到来时,将调用回调函数(例如:在 HubListener 的子类中的 onExtendedDeviceData(...) 方法,或 GF.startDataNotification(...) 的用户回调函数)

数据格式:

通知数据类型 数据包长度 首字节数值 数据内容* 注释
Accelerator 13 0x01 (NTF_ACC_DATA) Accelerator_X(4 Byte long), Accelerator_Y, Accelerator_Z x、y、z轴的加速度值,采用q15格式。将其除以65536.0f可获得实际浮点数值
Gyroscope 13 0x02 (NTF_GYRO_DATA) Gyroscope_X(4 Byte long), Gyroscope_Y, Gyroscope_Z x、y、z轴的陀螺仪数据,采用q15格式。将其除以65536.0f可获得实际浮点数值
Magnetometer 13 0x03 (NTF_MAG_DATA) Gyroscope_X(4 Byte long), Compass_Y, Compass_Z x、y、z轴的磁力计数据,采用q15格式。将其除以65536.0f可获得实际浮点数值
Euler Angle 13 0x04 (NTF_EULER_DATA) Pitch(4 Byte float), Roll, Yaw 欧拉角数据单位为度。俯仰角(Pitch)和偏航角(Yaw)范围均为[-180, 180],翻滚角(Roll)范围为[-90, 90]
Quaternion 17 0x05 (NTF_QUAT_FLOAT_DATA) Quaternion_W(4 Byte float), Quaternion_X, Quaternion_Y, Quaternion_Z 四元数,是简单的超复数
Rotation Matrix 37 0x06 (NTF_ROTA_DATA) Rot[0][0], Rot[0][1], Rot[0][2], Rot[1][0],... 这是一个3x3旋转矩阵,数据类型为long型。前3个4字节整数表示矩阵的第一行,后续依次为第二行和第三行
Gesture 3 0x07 (NTF_EMG_GEST_DATA) Gesture identify(1 Byte uint), Probability(1 Byte uint) 概率值的范围在[0, 100]之间
Raw EMG 129 0x08 (NTF_EMG_ADC_DATA) CH0,CH1...CH7, CH0,CH1...CH7, ... 数据包长度取决于EMG(肌电图)的配置,默认长度为129字节。当分辨率设置为8时,每个通道的数据由1字节表示;若分辨率设为12,则每个通道的数据需要2字节表示
Mouse NA 0x09 (NTF_HID_MOUSE) NA 当前不支持此功能
Joystick NA 0x0A (NTF_HID_JOYSTICK) NA 当前不支持此功能
Device Status 2 0x0B (NTF_DEV_STATUS) bit0 is for Recenter status, bit1 is for USB insert, bit2 is for USB unplug, bit3 is for motionless status; bit4 - bit7 is reserved 使用1字节表示新设备状态
Log Message >= 1 0x0C (NTF_LOG_DATA) log message string

* : 从数据包的第二个字节开始


gForce数据获取示例

EMG原始数据获取示例

注意: 此处仅包含数据相关函数,完整示例请参考SDK list中的代码.

C++

1. 实现 HubListener 接口

  class HubListenerImpl : public HubListener{...}

2. 配置 EMG 数据

调用 DeviceSetting::setEMGRawDataConfig(...) 来配置EMG数据. 第一个参数是采样率(单位:hz), 第二个参数是通道掩码, 第三个参数是数据包长度, 第四个参数是ADC分辨率, 第五个参数是回调函数.

3. 打开数据通知

调用 DeviceSetting::setDataNotifySwitch(...) 来打开EMG原始数据通知. 将第一个参数设置为DeviceSetting::DNF_EMG_RAW

4. 提取EMG数据等

void HubListenerImpl::onExtendedDeviceData(SPDEVICE device, DeviceDataType dataType, gfsPtr<const vector<GF_UINT8>> data) override
{
  auto ptr = data->data();

  switch (dataType) {
  case DeviceDataType::DDT_EMGRAW:
      for (size_t i = 0; i < data->size(); i++)
      {
        //for 8bpp mode
        printf("Emg data [%d] = %u\n", i, *(reinterpret_cast<const uint8_t*>(ptr++)));

        //for 12bpp mode
        //   printf("Emg data [%d] = %u\n", i, *(reinterpret_cast<const uint16_t*>(ptr)));
        //   ptr += 2;
      }

    break;

  case DeviceDataType::DDT_GYROSCOPE:
      //... extract gyroscope data form 'data'
    break;

  default:
    break;
  }
}

Python

DATA_LEN = 128

def ondata(data):
    if data[0] == NotifDataType['NTF_EMG_ADC_DATA'] and len(data) == DATA_LEN + 1:
            # Data for EMG CH0~CHn repeatedly.
            # Resolution set in setEmgRawDataConfig:
            #   8: one byte for one channel
            #   12: two bytes in LSB for one channel.
            # eg. 8bpp mode, data[1] = channel[0], data[2] = channel[1], ... data[8] = channel[7]
            #                data[9] = channel[0] and so on
            # eg. 12bpp mode, {data[2], data[1]} = channel[0], {data[4], data[3]} = channel[1] and so on
            for i in range(1, DATA_LEN):
                print(data[i])

def set_cmd_cb(resp):
    print('Command result: {}'.format(resp))

GF = GForceProfile()
GF.setEmgRawDataConfig(sampRate = 650, channelMask = 0xFF, dataLen = DATA_LEN, resolution = 8, cb = set_cmd_cb, timeout = 1000)
GF.setDataNotifSwitch(DataNotifFlags['DNF_EMG_RAW'], set_cmd_cb, timeout = 1000)
GF.startDataNotification(ondata)

button = input()

if len(button) != 0:
    GF.stopDataNotification()
    GF.setDataNotifSwitch(DataNotifFlags['DNF_OFF'], set_cmd_cb, timeout = 1000)

CSharp

1. 继承 HubListener 类并实现虚函数.

  class Listener : HubListener{...}

2. 调用 Device::setEmgConfig(...)来配置EMG数据

connectedDevice.setEmgConfig(650/*sampleRateHz*/, 0x00FF/*interestedChannels*/, 128/*packageDataLength*/, 8/*adcResolution*/, (Device dev, uint resp) =>
{
  // Process the result
});

3. 调用 Device::setDataSwitch(...)打开EMG原始数据通知

connectedDevice.enableDataNotification(0); // Stop notification temporary

connectedDevice.setDataSwitch((uint)DataNotifFlags.DNF_EMG_RAW/*and other data flags you want*/, (Device dev, uint resp) =>
{
    System.Console.WriteLine("setDataSwitch, response : {0}", (RetCode)resp);

    if ((RetCode)resp == RetCode.GF_SUCCESS)
    {
        dev.enableDataNotification(1);  // Enable notification
    }
});

3. 打印EMG原始数据

class Listener : HubListener
{
  public override void onExtendedDeviceData(Device device, Device.DataType type, byte[] data)
  {
    if (type == Device.DataType.Emgraw)
    {
        System.Console.Write("Emg data len: {0}, data:" , data.Length);

        var sb = new StringBuilder("{");

        foreach (var b in data)
        {
            sb.Append(b + ",");
        }

        sb.Remove(sb.Length - 1, 1);
        sb.Append("}");

        System.Console.WriteLine(sb.ToString());
    }
  }
}

注意: 配置数据类型及启动/停止数据通知时,应关闭数据传输