Files
fmviewer3/project/fm_viewer/data/rm_sensordata.h
2026-02-21 17:11:31 +09:00

329 lines
8.9 KiB
C++

#ifndef RM_SENSORDATA_H
#define RM_SENSORDATA_H
#include <stdio.h>
#include <stdint.h>
#include <vector>
#if !defined(BBEXTRACT)
#include "../rm_include.h"
#endif // #if !defined(BBEXTRACT)
#if !defined(MIN)
#define MIN(a,b) (((a)<(b))?(a):(b))
#endif
#if !defined(MAX)
#define MAX(a,b) (((a)>(b))?(a):(b))
#endif
#include "rm_format_avi.h"
#define DEBUG_SENSOR_DATA 0
#define GPRMC_VALID_CHECK 1
#define NUM_SENSOR_DATA 3 // XYZ
#define SENS_PACKET_SIZE (NUM_SENSOR_DATA * sizeof(float))
#if (RM_MODEL_EMT_KR)
// 모든 자막에 GPS+SENSOR 같은 숫자로 존재
typedef struct _NMEA_INFO
{
uint16_t nYear; // (UTC)년(+9시간)
uint8_t nMonth; // (UTC)월
uint8_t nDay; // (UTC)일
uint8_t nHour; // (UTC)시
uint8_t nMin; // (UTC)분
uint8_t nSec; // (UTC)초
uint8_t reserved; // ... (64 bit pack)
double Latitude; // 위도
double Longitude; // 경도
float Speed; // 속도 (Km/h)
float x;
float y;
float z;
float Voltage; // 전압
float Temperature; // 온도
uint8_t nStatus; // 상태(0,1)
uint8_t nAngle; // 방위각
#if (USE_TRIGGER)
uint8_t eTrigger; // 트리거 E (255 가 아닌 위치index 가 발생위치임)
uint8_t mTrigger; // " M (255 가 아닌 위치index 가 발생위치임)
uint8_t reserved2[4]; // 64 bit pack
#else // USE_TRIGGER
uint8_t reserved2[6]; // 64 bit pack
#endif // USE_TRIGGER
} NMEA_INFO;
#else // #if (RM_MODEL_EMT_KR)
typedef struct _NMEA_INFO
{
uint16_t nYear; // (UTC)년(+9시간)
uint8_t nMonth; // (UTC)월
uint8_t nDay; // (UTC)일
uint8_t nHour; // (UTC)시
uint8_t nMin; // (UTC)분
uint8_t nSec; // (UTC)초
uint8_t reserved; // ... (64 bit pack)
double Latitude; // 위도
double Longitude; // 경도
double Speed; // 속도 (Km/h)
uint8_t nStatus; // 상태(0,1)
uint8_t nAngle; // 방위각
uint8_t reserved2[6]; // 64 bit pack
} NMEA_INFO;
#endif //
#if (RM_MODEL == RM_MODEL_TYPE_ADT_CAPS && !SUB_MODEL_CARROT_EMT)
typedef struct _SEN {
float x;
float y;
float z;
float gcal;
uint32_t drive;
uint32_t parking;
} SEN;
#endif // RM_MODEL_TYPE_ADT_CAPS
class RMSensorData
{
public:
typedef enum
{
FILE_TYPE_AVI = 0,
FILE_TYPE_MOV = 1, // MP4
} FILE_TYPE;
RMSensorData(FILE* f,FILE_TYPE type);
~RMSensorData();
QString modelName;
uint32_t getSensorCount()
{
return _sensorCount;
}
#if (RM_MODEL_EMT_KR)
const NMEA_INFO* getSensor()
{
return _sensorData;
}
uint32_t getGPSCount()
{
return _bGPSExist ? _sensorCount : 0;
}
const NMEA_INFO* getGPS()
{
return _bGPSExist ? _sensorData : NULL;
}
const bool getGPSCoord(double ratio,double* lat, double* lon)
{
if(_bGPSExist)
{
unsigned int index = (int)((double)_sensorCount * ratio);
if(index <= _sensorCount) // 마지막 1초는 오차 범위
{
index = MIN(index,_sensorCount-1);
*lat = _sensorData[index].Latitude;
*lon = _sensorData[index].Longitude;
return true;
}
}
return false;
}
const double getGPSSpeed(double ratio)
{
if(_bGPSExist)
{
unsigned int index = (int)((double)_sensorCount * ratio);
if(index <= _sensorCount) // 마지막 1초는 오차 범위
{
index = MIN(index,_sensorCount-1);
//qInfo() << "SPD:" << index << _gpsData[index].nStatus << _gpsData[index].Speed;
return _sensorData[index].nStatus == 1 ? _sensorData[index].Speed : -1;
}
}
return -1;
}
bool getGPSPosition(double ratio,double* lonX, double* latY, double* speed)
{
if(_bGPSExist)
{
unsigned int index = (int)((double)_sensorCount * ratio);
if(index < _sensorCount && _sensorData[index].nStatus == 1)
{
*lonX = _sensorData[index].Longitude;
*latY = _sensorData[index].Latitude;
*speed = _sensorData[index].Speed;
return true;
}
}
return false;
}
#else // RM_MODEL_EMT_KR
const float* getSensor()
{
return _sensorData;
}
uint32_t getGPSCount()
{
return _bGPSExist ? _gpsCount : 0;
}
const NMEA_INFO* getGPS()
{
return _bGPSExist ? _gpsData : NULL;
}
const bool getGPSCoord(double ratio,double* lat, double* lon)
{
if(_bGPSExist)
{
unsigned int index = (int)((double)_gpsCount * ratio);
if(index <= _gpsCount) // 마지막 1초는 오차 범위
{
index = MIN(index,_gpsCount-1);
*lat = _gpsData[index].Latitude;
*lon = _gpsData[index].Longitude;
return true;
}
}
return false;
}
const double getGPSSpeed(double ratio)
{
#if !(SPEED_ALWAYS_EXITS)
if(_bGPSExist)
#endif
{
unsigned int index = (int)((double)_gpsCount * ratio);
if(index <= _gpsCount) // 마지막 1초는 오차 범위
{
index = MIN(index,_gpsCount-1);
#if (SPEED_ALWAYS_EXITS)
//qInfo() << "SPD:" << index << _gpsData[index].nStatus << _gpsData[index].Speed;
return _gpsData[index].Speed;
#else
//qInfo() << "SPD:" << index << _gpsData[index].nStatus << _gpsData[index].Speed;
return _gpsData[index].nStatus == 1 ? _gpsData[index].Speed : -1;
#endif
}
}
return -1;
}
bool getGPSPosition(double ratio,double* lonX, double* latY, double* speed)
{
if(_bGPSExist)
{
unsigned int index = (int)((double)_gpsCount * ratio);
if(index < _gpsCount && _gpsData[index].nStatus == 1)
{
*lonX = _gpsData[index].Longitude;
*latY = _gpsData[index].Latitude;
*speed = _gpsData[index].Speed;
return true;
}
}
return false;
}
#if (CLIP_SENSOR_DATA)
void clipWithDuration(qint64 duration);
void clipSensorCount(int number);
void clipGPSCount(int number);
void fixGPS();
#endif
#endif // RM_MODEL_EMT_KR
#if (USE_TRIGGER)
float triggerE; // 트리거 위치 (ratio 0~1.0)
float triggerM;
#endif // USE_TRIGGER
#if defined(MODEL_BBVIEWER) && (!MODEL_WATEX)
const double getOBDSpeed(double ratio)
{
if(_sensorData != NULL && _sensorCount > 0)
{
unsigned int index = (int)(((double)_sensorCount) * ratio);
//qInfo() << "SENSOR INDEX:" << index;
if(index < _sensorCount)
{
return _OBDSpeed[index];
}
}
return true;
}
#endif // BB
// 재생시간과 센서 데이터 동기화 (짧으면 추가, 길면 자르기)
void processWithDuration(qint64 ms);
private:
#if (CLIP_SENSOR_DATA)
int _skipSensorCount;
#endif
bool _bGPSExist;
long _nLastAngle[2]; // RMC 데이터 처리용
#if(RM_MODEL_EMT_KR)
uint32_t _sensorCount;
NMEA_INFO* _sensorData;
#else // RM_MODEL_EMT_KR
#if (RM_MODEL == RM_MODEL_TYPE_KEIYO1 || \
RM_MODEL == RM_MODEL_TYPE_MBJ5010 || \
RM_MODEL == RM_MODEL_TYPE_FC_DR232W || \
RM_MODEL == RM_MODEL_TYPE_BV2000 || \
RM_MODEL == RM_MODEL_TYPE_MH9000 )
int _sensorFPS;
#endif
uint32_t _gpsCount;
uint32_t _sensorCount;
#if defined(BBEXTRACT)
GSENSOR* _sensorData;
#else
float* _sensorData;
#endif
NMEA_INFO* _gpsData;
#if (MODEL_BBVIEWER && !MODEL_WATEX)
float* _OBDSpeed; // GPS 속도인지 ODB 속도인지 확인
#endif
#endif // !RM_MODEL_EMT_KR
#if (FILE_FORMAT_MOV)
bool loadMOV(FILE* f);
#if !(RM_MODEL_EMT_KR)
#if(RM_MODEL == RM_MODEL_TYPE_MH9000)
bool loadMOVGPSNR(void* p,uint32_t count);
#else // RM_MODEL_TYPE_MH9000
bool loadMOVGPSNR(void* p,uint32_t count, void* ps, uint32_t sensorCount);
//bool loadMOVGPSNR(void* p,uint32_t count);
#endif // RM_MODEL_TYPE_MH9000
#endif // #if !(RM_MODEL_EMT_KR)
#endif // FILE_FORMAT_MOV
#if (FILE_FORMAT_AVI)
bool loadAVIRiff(FILE* f); // TYPE 1
#if (AVI_CHUNHO_SENSOR_FORMAT_1)
bool loadAVIChunck(uint8_t* gps, size_t gps_size,uint8_t* sensor, size_t sensor_size);
#endif
#if (SENSOR_AVI_SUBTITLE)
bool loadAVISubTitle(QList<char*>* subTitles); // AVI TYPE 2 불러오기
#endif
#endif // FILE_FORMAT_AVI
};
#endif // RM_SENSORDATA_H