diff --git a/app/src/main/cpp/PtzController.cpp b/app/src/main/cpp/PtzController.cpp index a284f064..098f3583 100644 --- a/app/src/main/cpp/PtzController.cpp +++ b/app/src/main/cpp/PtzController.cpp @@ -103,13 +103,17 @@ void PtzController::ExitAndWait() void PtzController::PtzProc() { - PTZ_STATE state = PTZS_POWER_OFF; + PROC_PTZ_STATE state = PTZS_POWER_OFF; SERIAL_CMD cmd; + PTZ_STATE ptz_state; bool hasCmd = false; + int i=0; std::shared_ptr powerCtrl; time_t selfTestingStartTime = 0; time_t selfTestingWaitTime = 0; + time_t PTZ_preset_start_time=0; + time_t PTZ_preset_wait_time=0; while(true) { @@ -153,10 +157,28 @@ void PtzController::PtzProc() time_t timeout = time(NULL) - selfTestingStartTime; if (timeout >= selfTestingWaitTime) { + XYLOG(XYLOG_SEVERITY_INFO, "超时(%d秒)未收到云台自检结束应答,状态改为空闲!", timeout); state = PTZS_IDLE; m_sem.release(); continue; } + else + { + if(timeout >= CAMERA_SELF_TEST_TIME) + { + //XYLOG(XYLOG_SEVERITY_INFO, "开始查询云台自检状态!timeout=%d秒", timeout); + if(0 == QueryPtzState(&ptz_state, QUERY_PTZ_STATE, cmd.serfile, cmd.baud, cmd.addr)) + { + if(0 == ptz_state.ptz_status) + { + XYLOG(XYLOG_SEVERITY_INFO, "收到云台自检结束应答,状态改为空闲!timeout=%d秒", timeout); + state = PTZS_IDLE; + m_sem.release(); + continue; + } + } + } + } std::this_thread::sleep_for(std::chrono::milliseconds(1000)); m_sem.release(); continue; @@ -178,6 +200,7 @@ void PtzController::PtzProc() selfTestingStartTime = time(NULL); selfTestingWaitTime = cmd.photoParams->mPhotoInfo.selfTestingTime; state = PTZS_SELF_TESTING; + XYLOG(XYLOG_SEVERITY_INFO, "1、收到拍照指令,摄像机从关机状态改为自检状态!"); m_locker.lock(); m_cmds.insert(m_cmds.begin(), cmd); @@ -186,12 +209,33 @@ void PtzController::PtzProc() continue; } } + XYLOG(XYLOG_SEVERITY_INFO, "2、收到拍照指令,state=%d!", state); state = PTZS_TAKING_PHOTO; if (cmd.preset != 0 && cmd.preset != 0xFF) { CameraPhotoCmd(0, cmd.channel, MOVE_PRESETNO, 0, cmd.preset, cmd.serfile, cmd.baud, cmd.addr); - std::this_thread::sleep_for(std::chrono::milliseconds(10 * 1000)); + + XYLOG(XYLOG_SEVERITY_INFO, "摄像机拍照前开始调用预置点!state=%d", state); + PTZ_preset_start_time = time(NULL); + PTZ_preset_wait_time = MOVE_PRESET_WAIT_TIME; + for(;;) + { + if(0 == QueryPtzState(&ptz_state, QUERY_PTZ_STATE, cmd.serfile, cmd.baud, cmd.addr)) + { + if(0 == ptz_state.ptz_status) + { + XYLOG(XYLOG_SEVERITY_INFO, "摄像机拍照前调用预置点,收到移动结束应答!移动时长=%d秒 state=%d", time(NULL)-PTZ_preset_start_time, state); + break; + } + } + if(time(NULL) - PTZ_preset_start_time >= PTZ_preset_wait_time) + { + XYLOG(XYLOG_SEVERITY_INFO, "摄像机拍照前调用预置点,摄像机在%d秒内未收到调用预置点结束应答!state=%d", PTZ_preset_wait_time, state); + break; + } + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + } } m_pPhoneDevice->TakePhotoWithNetCamera(cmd.photoParams->mPhotoInfo, cmd.photoParams->mPath, cmd.photoParams->mOsds, powerCtrl); state = PTZS_IDLE; @@ -203,22 +247,36 @@ void PtzController::PtzProc() { if (!powerCtrl) { - powerCtrl = std::make_shared(cmd.delayTime); + powerCtrl = std::make_shared(150); selfTestingStartTime = time(NULL); - selfTestingWaitTime = cmd.ts; + selfTestingWaitTime = 150; state = PTZS_SELF_TESTING; + m_sem.release(); + XYLOG(XYLOG_SEVERITY_INFO, "收到开机指令,摄像机从关机状态改为自检状态!设置的自检等待时间%d秒", selfTestingWaitTime); } } + else + { + XYLOG(XYLOG_SEVERITY_INFO, "收到开机指令,摄像机处于state=%d!", state); + } break; case CLOSE_TOTAL: if (state == PTZS_POWER_OFF) { + XYLOG(XYLOG_SEVERITY_INFO, "收到关机指令,摄像机本来就处于关机状态!"); // Do Nothing } else { + XYLOG(XYLOG_SEVERITY_INFO, "收到关机指令,通知云台准备关机!state=%d", state); + for(i=0; i<3; i++) + { + if(0 == QueryPtzState(&ptz_state, NOTIFY_PTZ_CLOSE, cmd.serfile, cmd.baud, cmd.addr)) + break; + } powerCtrl.reset(); state = PTZS_POWER_OFF; + XYLOG(XYLOG_SEVERITY_INFO, "关闭云台电源!state=%d", state); } break; default: diff --git a/app/src/main/cpp/PtzController.h b/app/src/main/cpp/PtzController.h index b19541f1..cfd712f0 100644 --- a/app/src/main/cpp/PtzController.h +++ b/app/src/main/cpp/PtzController.h @@ -14,7 +14,7 @@ #include #include -enum PTZ_STATE +enum PROC_PTZ_STATE { PTZS_POWER_OFF = 0, PTZS_IDLE = 1, @@ -23,6 +23,9 @@ enum PTZ_STATE PTZS_TAKING_PHOTO = 4, }; +#define CAMERA_SELF_TEST_TIME 60 /* Camera self-test time (excluding PTZ self-test)*/ +#define MOVE_PRESET_WAIT_TIME 20 /* Waiting for the maximum time for the PTZ to move to the preset position*/ + class PtzPhotoParams { public: diff --git a/app/src/main/cpp/SensorsProtocol.cpp b/app/src/main/cpp/SensorsProtocol.cpp index a54939f8..5172e73c 100644 --- a/app/src/main/cpp/SensorsProtocol.cpp +++ b/app/src/main/cpp/SensorsProtocol.cpp @@ -1,7 +1,6 @@ #include #include -#include #include #include #include @@ -24,13 +23,14 @@ #include #include -#include +#include "AndroidHelper.h" #include "SensorsProtocol.h" //#include "Eint.h" #include pthread_mutex_t serial_mutex = PTHREAD_MUTEX_INITIALIZER; // 定义一个互斥锁 pthread_mutex_t camera_mutex = PTHREAD_MUTEX_INITIALIZER; // 定义一个互斥锁 +pthread_mutex_t bd_mutex = PTHREAD_MUTEX_INITIALIZER; // 定义一个互斥锁 SIO_PARAM_SERIAL_DEF serialport[MAX_SERIAL_PORT_NUM]; @@ -41,411 +41,6 @@ AI_DEF rallypntmsg[6][RALLY_DATA_NUM]; AI_DEF slantpntmsg[6][SLANTANGLE_DATA_NUM]; char logPath[512]; -#if 0 -/********************************************************************************* -* 气象数据处理 * -**********************************************************************************/ -static void PortDataProcess(void) -{ - float fvalue, fcorvalue, *fvalua, frnb/*, fwind*/; - //uint16_t uDevAddr; - unsigned char cmdidx; - int i, j, aipnt, datanum; - SIO_PARAM_SERIAL_DEF *pPortParam; - char szbuf[64]; - - pPortParam = &serialport; - //取出装置地址,开始处理地址+++ - if (0x02 == pPortParam->m_au8RecvBuf[5]) - { - //pPortParam->devaddr = pPortParam->m_au8RecvBuf[4]; - return; - } - cmdidx = pPortParam->m_au8RecvBuf[5]; -#if 0 - aipnt = pPortParam->SameTypeDevIdx; - uDevAddr = serialport->m_au8RecvBuf[4]; - if (0 == srdt.IsReadWireTem) - { - if (uDevAddr != pPortParam->devaddr) - return; - } -#endif - fvalua = &fvalue; - datanum = pPortParam->m_au8RecvBuf[6]; - if ((0x08 != cmdidx) && (0x09 != cmdidx)) - return; - - for (i = 0, j = 7; (i < datanum) && (j < 6 + pPortParam->m_au8RecvBuf[1]); i++, j += 5) - { - if (0x08 == cmdidx) - fvalue = (pPortParam->m_au8RecvBuf[j + 1] << 24) + (pPortParam->m_au8RecvBuf[j + 2] << 16) - + (pPortParam->m_au8RecvBuf[j + 3] << 8) + pPortParam->m_au8RecvBuf[j + 4]; - else - { - *(u_char *)fvalua = pPortParam->m_au8RecvBuf[j + 4]; - *((u_char *)fvalua + 1) = pPortParam->m_au8RecvBuf[j + 3]; - *((u_char *)fvalua + 2) = pPortParam->m_au8RecvBuf[j + 2]; - *((u_char *)fvalua + 3) = pPortParam->m_au8RecvBuf[j + 1]; - } - switch (pPortParam->m_au8RecvBuf[j]) - { - case 1: /*温度*/ - weatherpntmsg[0] = fvalue; - LOGE("温度:%0.3f ", fvalue); - break; - case 2: /*气压*/ - weatherpntmsg[5] = fvalue; - LOGE("气压:%0.3f ", fvalue); - break; - case 3: /*湿度*/ - weatherpntmsg[1] = fvalue; - LOGE("湿度:%0.3f ", fvalue); - break; - case 4: /*雨量*/ - break; - case 5: /*日照*/ - break; - case 6: /*风速*/ - weatherpntmsg[2] = fvalue; - LOGE("风速:%0.3f ", fvalue); - break; - case 7: /*风向*/ - weatherpntmsg[3] = fvalue; - LOGE("风向:%0.3f ", fvalue); - break; - case 8: /*拉力*/ - case 9: /*倾角传感器X轴倾角*/ - case 10: /*倾角传感器Y轴倾角*/ - case 11: /*测温球导线温度*/ - case 12: /*测温球内部温度*/ - break; - case 13: /*测温球导线X轴倾角*/ - break; - case 14: /*测温球导线Y轴倾角*/ - break; - case 15: /*测温球导线电流*/ - break; - case 16: /*测温球电池电压*/ - break; - case 17: /*A相泄漏电流平均值;*/ - break; - case 18: /*A相泄漏电流最大值;*/ - break; - case 19: /*A相超过3mA的脉冲频次*/ - break; - case 20: /*A相超过10mA的脉冲频次*/ - break; - case 21: /*B相泄漏电流平均值;*/ - break; - case 22: /*B相泄漏电流最大值;*/ - break; - case 23: /*B相超过3mA的脉冲频次*/ - break; - case 24: /*B相超过10mA的脉冲频次*/ - case 25: /*C相泄漏电流平均值;*/ - case 26: /*C相泄漏电流最大值;*/ - case 27: /*C相超过3mA的脉冲频次*/ - case 28: /*C相超过10mA的脉冲频次*/ - break; - } - } -} - -/*************************************************************** -* 按照协议格式化接收数据 * -***************************************************************/ -static void RecvData(u_char *buf, int len)// 规约读数据处理 -{ - int i, ictime; - //uint16_t crc, check; - SIO_PARAM_SERIAL_DEF *pPortParam; - - pPortParam = &serialport; - ictime = (int)time(NULL); - - if (pPortParam->m_iRecvLen == 0) - { - pPortParam->iRecvTime = ictime; - } - else - { - if ((ictime - pPortParam->iRecvTime > 6) || (ictime - pPortParam->iRecvTime < 0)) - pPortParam->iRecvTime = ictime; - else if (ictime - pPortParam->iRecvTime > 2) - { - pPortParam->m_iRecvLen = 0; - pPortParam->m_iRevStatus = 0; - } - } - - for (i = 0; i < len; i++) - { - switch (pPortParam->m_iRevStatus) - { - case 0: // 0x68 - pPortParam->m_iRecvLen = 0; - pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i]; - if (0x68 == buf[i]) - pPortParam->m_iRevStatus++; - else - pPortParam->m_iRevStatus = 18; - break; - case 1: // len1 - pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i]; - pPortParam->m_iRevStatus++; - break; - case 2: // len2 - pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i]; - if (buf[i] == pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen - 2]) - { - pPortParam->m_iRevStatus++; - pPortParam->m_iNeedRevLength = buf[i] + 5; - } - else - pPortParam->m_iRevStatus = 18; - break; - case 3: // 0x68 - pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i]; - pPortParam->m_iNeedRevLength--; - if (0x68 == buf[i]) - pPortParam->m_iRevStatus++; - else - pPortParam->m_iRevStatus = 18; - break; - case 4: // 正确接收数据 - pPortParam->m_iNeedRevLength--; - pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i]; - if (pPortParam->m_iNeedRevLength > 0) - break; - if (buf[i] != 0x16) - { - pPortParam->m_iRevStatus = 18; - break; - } - - //if(CheckLpcError(serialport->m_au8RecvBuf, pPortParam->m_iRecvLen) == TRUE) - { - PortDataProcess(); - pPortParam->m_iRevStatus = 0; - pPortParam->RevCmdFlag = 1; - } - pPortParam->m_iRecvLen = 0; - break; - case 255:// 错误接收数据 - default: - if (buf[i] == 0x68) - { - pPortParam->m_iRevStatus = 1; - pPortParam->m_iRecvLen = 1; - pPortParam->m_au8RecvBuf[0] = buf[i]; - } - else if (buf[i] == 0x16) - { - pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i]; - pPortParam->m_iRevStatus = 0; - pPortParam->m_iRecvLen = 0; - } - else - { - pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i]; - if (pPortParam->m_iRecvLen > 200) - { - pPortParam->m_iRecvLen = 0; - } - } - break; - } - } -} - -static int64_t get_msec(void) -{ - struct timeval tv; - - gettimeofday(&tv, NULL); - int64_t time_in_msec = tv.tv_sec * 1000 + tv.tv_usec / 1000; - - return time_in_msec; -} -//int inum =0; -//int itimecnt=0; -static int weather_comm(SERIAL_PARAM weatherport) -{ - int fd = -1; - int len, i, ret, icnt = 0; - int64_t ictime, iruntime, isendtime, irecvtime; - unsigned char sendbuf[] = { 0x68,0x00,0x00,0x68,0x01,0x09,0x0a,0x16 }; - char recvbuf[256], szbuf[512]; - //char serial_description[] = "/dev/ttyS0"; - -#if 0 - DIR *dir = opendir("/dev"); - if (dir == NULL) { - LOGE("_test_ opendir"); - return -1; - } - - // 读取目录项 - struct dirent *entry; - while ((entry = readdir(dir)) != NULL) { - // 过滤出串口设备,通常以"ttyS"或"ttyUSB"开头 - if ((strncmp(entry->d_name, "ttyS2", 5) == 0) || - (strncmp(entry->d_name, "ttyS0", 5) == 0)) { - LOGE("_test_ Found serial port: %s\n", entry->d_name); - } - } - - // 关闭目录 - closedir(dir); -#endif - serialport.RevCmdFlag = 1; - serialport.m_iRecvLen = 0; - serialport.m_iRevStatus = 0; - - set12VEnable(true); - setCam3V3Enable(true); - setRS485Enable(true); - sleep(2); - //ictime = (int)time(NULL); - ictime = get_msec(); - for (;;) - { - if (fd < 0) - { - fd = open(weatherport.pathname, O_RDWR | O_NDELAY); - //fd = open(weatherport.pathname, O_RDWR | O_NOCTTY); - if (fd < 0) - { - LOGE("_test_ open serial error \n"); - perror(weatherport.pathname); - return -1; - } - - ret = set_port_attr(fd, weatherport.baudrate, weatherport.databit, weatherport.stopbit, weatherport.parity, 0, 0);/*9600 8n1 */ - if (ret < 0) - { - LOGE("_test_ set uart arrt faile \n"); - return -1; - } - } - - usleep(10000); - //iruntime = (int)time(NULL); - iruntime = get_msec(); - if ((iruntime - ictime > 120000) || (iruntime - ictime < 0)) - ictime = iruntime; - if (iruntime - ictime > 20000) - { - memset(szbuf, 0, sizeof(szbuf)); - sprintf(szbuf, "气象采样时间=%0.3f秒,停止采样!", (iruntime - ictime) / 1000.0); - LOGE("%s", szbuf); - break; - } - - if (1 == serialport.RevCmdFlag) - { - set485WriteMode(); - - len = write(fd, sendbuf, sizeof(sendbuf));/* 向串囗发送字符串 */ - serialport.RevCmdFlag = 0; - LOGE("发送命令时间差%ld毫秒", get_msec() - isendtime); - //isendtime = time(NULL); - isendtime = get_msec(); - if (len < 0) { - LOGE("write data error \n"); - return -1; - } - else { - memset(szbuf, 0, sizeof(szbuf)); - sprintf(szbuf, "Send:"); - for (i = 0; i < len; i++) { - sprintf(szbuf, "%s %02X", szbuf, sendbuf[i]); - } - LOGE("%s", szbuf); - //icnt = 0; - //inum++; - } - tcdrain(fd); - //usleep(50000); - } - else - { - //irecvtime = time(NULL); - irecvtime = get_msec(); - if ((irecvtime - isendtime > 6000) || (irecvtime - isendtime < 0)) - isendtime = irecvtime; - if (irecvtime - isendtime > 300) - { - LOGE("传感器超过%ld毫秒未应答", irecvtime - isendtime); - serialport.RevCmdFlag = 1; - serialport.m_iRecvLen = 0; - serialport.m_iRevStatus = 0; - close(fd); - fd = -1; - continue; - } - } - set485ReadMode(); - memset(recvbuf, 0, sizeof(recvbuf)); - len = read(fd, recvbuf, sizeof(recvbuf));/* 在串口读取字符串 */ - if (len < 0) { - LOGE("serial read error \n"); - continue; - } - if (0 == len) - { - //icnt++; - continue; - } - memset(szbuf, 0, sizeof(szbuf)); - sprintf(szbuf, "Recv:"); - for (i = 0; i < len; i++) { - sprintf(szbuf, "%s %02X", szbuf, recvbuf[i]); - } - __android_log_print(ANDROID_LOG_INFO, "serial", "%s", szbuf); - RecvData((u_char*)recvbuf, len); - //LOGE("一周期空循环次数%d, 读取次数%d, 时间:%d %d", icnt, inum, (int)time(NULL), itimecnt); - icnt = 0; - //serialport.RevCmdFlag =1; - } - - close(fd); - set12VEnable(false); - setCam3V3Enable(false); - setRS485Enable(false); - - //exit(-1); - return(0); -} - -int serial_port_comm() -{ - SERIAL_PARAM portparm; - - //struct timeval tv; - - //gettimeofday(&tv, NULL); - //int64_t time_in_microseconds = tv.tv_sec * 1000000 + tv.tv_usec; - - //LOGE("Current time in microseconds: %ld\n", time_in_microseconds); - -#if 1 - memset(portparm.pathname, 0, sizeof(portparm.pathname)); - sprintf(portparm.pathname, "/dev/ttyS0"); - portparm.parity = 'N'; - portparm.databit = 8; - portparm.baudrate = B9600; - memset(portparm.stopbit, 0, sizeof(portparm.stopbit)); - sprintf(portparm.stopbit, "1"); -#endif - //itimecnt = (int)time(NULL); - - //for(;;) - weather_comm(portparm); - return 0; -} -#endif extern int Gm_SetSerialPortParam(int commid); static speed_t getBaudrate(unsigned int baudrate) { @@ -523,111 +118,12 @@ void Gm_CloseSensorsPower() /* 关闭电源*/ //switch(port) /* 根据硬件具体布置最后调整,目前是微拍板子的来控制*/ -/* set12VEnable(false); - setCam3V3Enable(false); - setRS485Enable(false); -#if 0 - setInt(CMD_SET_WTH_POWER, 0); - setInt(CMD_SET_PULL_POWER, 0); - setInt(CMD_SET_ANGLE_POWER, 0); - setInt(CMD_SET_OTHER_POWER, 0); - setInt(CMD_SET_PIC1_POWER, 0); - - sleep(3); - igpio = getInt(CMD_SET_WTH_POWER); - igpio = getInt(CMD_SET_PULL_POWER); - igpio = getInt(CMD_SET_ANGLE_POWER); - igpio = getInt(CMD_SET_OTHER_POWER); - igpio = getInt(CMD_SET_PIC1_POWER); -#endif -#if 1 - setInt(CMD_SET_SPI_POWER, 1); - setInt(CMD_SET_485_EN0, 1); - setInt(CMD_SET_485_EN1, 1); - setInt(CMD_SET_485_EN2, 1); - setInt(CMD_SET_485_EN3, 1); - setInt(CMD_SET_485_EN4, 1); -#else - setInt(CMD_SET_SPI_POWER, 0); - setInt(CMD_SET_485_EN0, 0); - setInt(CMD_SET_485_EN1, 0); - setInt(CMD_SET_485_EN2, 0); - setInt(CMD_SET_485_EN3, 0); - setInt(CMD_SET_485_EN4, 0); - sleep(3); - igpio = getInt(CMD_SET_SPI_POWER); - igpio = getInt(CMD_SET_485_EN0); - igpio = getInt(CMD_SET_485_EN1); - igpio = getInt(CMD_SET_485_EN2); - igpio = getInt(CMD_SET_485_EN3); - igpio = getInt(CMD_SET_485_EN4); -#endif -*/ } // 打开传感器电源 void Gm_OpenSensorsPower() { - //char iIoNo; -/* int igpio; - char szbuf[128]; - - //if(0 == port) - // return; - //sprintf(szbuf, "Open Sensors port %d Power!", port); - - //set12VEnable(true); - setCam3V3Enable(true); - setRS485Enable(true); - -#if 0 - setInt(CMD_SET_WTH_POWER, 0); - setInt(CMD_SET_PULL_POWER, 0); - setInt(CMD_SET_ANGLE_POWER, 0); - setInt(CMD_SET_OTHER_POWER, 0); - setInt(CMD_SET_PIC1_POWER, 0); -#else - setInt(CMD_SET_WTH_POWER, 1); - setInt(CMD_SET_PULL_POWER, 1); - setInt(CMD_SET_ANGLE_POWER, 1); - setInt(CMD_SET_OTHER_POWER, 1); - setInt(CMD_SET_PIC1_POWER, 1); - //sleep(3); - igpio = getInt(CMD_SET_WTH_POWER); - igpio = getInt(CMD_SET_PULL_POWER); - igpio = getInt(CMD_SET_ANGLE_POWER); - igpio = getInt(CMD_SET_OTHER_POWER); - igpio = getInt(CMD_SET_PIC1_POWER); - -#endif -#if 1 - setInt(CMD_SET_SPI_POWER, 1); - setInt(CMD_SET_485_EN0, 1); - setInt(CMD_SET_485_EN1, 1); - setInt(CMD_SET_485_EN2, 1); - setInt(CMD_SET_485_EN3, 1); - setInt(CMD_SET_485_EN4, 1); - - //sleep(3); - igpio = getInt(CMD_SET_SPI_POWER); - igpio = getInt(CMD_SET_485_EN0); - igpio = getInt(CMD_SET_485_EN1); - igpio = getInt(CMD_SET_485_EN2); - igpio = getInt(CMD_SET_485_EN3); - igpio = getInt(CMD_SET_485_EN4); - -#else - setInt(CMD_SET_485_EN0, 0); - setInt(CMD_SET_485_EN1, 0); - setInt(CMD_SET_485_EN2, 0); - setInt(CMD_SET_485_EN3, 0); - setInt(CMD_SET_485_EN4, 0); -#endif - - // 打开电源 - //switch(port) -*/ } // 查询传感器电源状态 @@ -1094,7 +590,7 @@ void testComm() CameraPhotoCmd(time(NULL), 1, 0, 6, 1, "/dev/ttyS0",38400, 1); sleep(5); - CameraPhotoCmd(time(NULL), 1, 10017, 0, 2, "/dev/ttyS1",38400, 1); + CameraPhotoCmd(time(NULL), 1, MOVE_PRESETNO, 0, 2, "/dev/ttyS1",38400, 1); sleep(5); CameraPhotoCmd(0, 1, MOVE_LEFT, 0, 0, "/dev/ttyS1",38400, 1); @@ -1105,7 +601,7 @@ void testComm() sleep(5); CameraPhotoCmd(0, 1, MOVE_UP, 0, 0, "/dev/ttyS1",38400, 1); sleep(5); - CameraPhotoCmd(0, 1, 10017, 0, 1, "/dev/ttyS1",38400, 1); + CameraPhotoCmd(0, 1, MOVE_PRESETNO, 0, 1, "/dev/ttyS1",38400, 1); sleep(5); sleep(5); //CameraPhotoCmd(0, 1, ZOOM_WIDE, 0, 0); @@ -1453,6 +949,7 @@ void Gm_FindAllSensorsCommand() case PELCO_P_PROTOCOL: /* 摄像机协议*/ case SERIALCAMERA_PROTOCOL: /* 串口摄像机协议*/ break; + default: break; } if (flag == -1) @@ -1849,7 +1346,9 @@ void CameraRecvData(SIO_PARAM_SERIAL_DEF *pPortParam, u_char *buf, int len) void CameraPhotoPortDataProcess(SIO_PARAM_SERIAL_DEF *curserial) { RTUMSG rtumsg; - int img_file_size, packetnum, iNo, packsize, i = 0, presetno, iphototime, pidx; + int img_file_size, packetnum, iNo, packsize, i = 0, j = 0, presetno, iphototime, pidx; + int datanum; + float fvalue; char szbuf[128]; uint16_t uDevAddr, datalen=0; uint8_t cmdidx, recvend; @@ -1990,6 +1489,87 @@ void CameraPhotoPortDataProcess(SIO_PARAM_SERIAL_DEF *curserial) curserial->RevCmdFlag = 1; curserial->FirstCmdTimeCnt = get_msec(); break; + case 0xA0: + sprintf(szbuf, "云台收到关电通知响应!"); + DebugLog(0, szbuf, 'I'); + curserial->SerialCmdidx = -1; + break; + case 0x08: + datanum = curserial->m_au8RecvBuf[6]; + memset(szbuf, 0, sizeof(szbuf)); + for (i = 0, j = 7; (i < datanum) && (j < 6 + datalen); i++, j += 5) + { + fvalue = (curserial->m_au8RecvBuf[j + 1] << 24) + (curserial->m_au8RecvBuf[j + 2] << 16) + + (curserial->m_au8RecvBuf[j + 3] << 8) + curserial->m_au8RecvBuf[j + 4]; + switch (curserial->m_au8RecvBuf[j]) + { + case 200: /* 云台状态*/ + curserial->ptz_state.ptz_process = curserial->m_au8RecvBuf[j + 1]; + curserial->ptz_state.ptz_status = curserial->m_au8RecvBuf[j+4]; + switch (curserial->ptz_state.ptz_process) + { + case 1: // 自检 + if (0 == curserial->ptz_state.ptz_status) + sprintf(szbuf, "云台自检结束!"); + else if (1 == curserial->ptz_state.ptz_status) + sprintf(szbuf, "云台正在自检!"); + else + sprintf(szbuf, "云台自检发生错误!"); + DebugLog(0, szbuf, 'I'); + break; + case 2: // 调用预置点 + if (0 == curserial->ptz_state.ptz_status) + sprintf(szbuf, "调用预置位结束,云台处于所调预置位!"); + else if (1 == curserial->ptz_state.ptz_status) + sprintf(szbuf, "调用预置位,云台正在前往所调预置位位置!"); + else if (2 == curserial->ptz_state.ptz_status) + sprintf(szbuf, "调用预置位时,机芯电源未打开!"); + else + sprintf(szbuf, "调用预置位时,发生了错误,未正确执行!"); + DebugLog(0, szbuf, 'I'); + break; + case 3: // 一般状态 + if (0 == curserial->ptz_state.ptz_status) + sprintf(szbuf, "云台处于静止状态!"); + else if (1 == curserial->ptz_state.ptz_status) + sprintf(szbuf, "云台正在运动!"); + else + sprintf(szbuf, "云台发生错误!"); + DebugLog(0, szbuf, 'I'); + break; + default: + sprintf(szbuf, "未知错误,云台应答错误!"); + DebugLog(0, szbuf, 'I'); + break; + } + break; + case 201: /* 云台预置点*/ + curserial->ptz_state.presetno = (curserial->m_au8RecvBuf[j + 3] << 8) + curserial->m_au8RecvBuf[j + 4]; + sprintf(szbuf, "云台预置点号=%d", curserial->ptz_state.presetno); + DebugLog(0, szbuf, 'I'); + break; + case 202: /* 云台坐标*/ + fvalue = (uint16_t)((curserial->m_au8RecvBuf[j + 1] << 8) + (curserial->m_au8RecvBuf[j + 2])); + fvalue /=100.0; + curserial->ptz_state.x_coordinate = fvalue; + fvalue = (uint16_t)((curserial->m_au8RecvBuf[j + 3] << 8) + (curserial->m_au8RecvBuf[j + 4])); + fvalue /=100.0; +#if 0 + if(fvalue < 180) + fvalue *= -1; + else + fvalue = 360-fvalue; +#endif + if(fvalue > 180) + fvalue -= 360; + curserial->ptz_state.y_coordinate = fvalue; + sprintf(szbuf, "云台坐标水平(X)=%0.2f°, 垂直(Y)=%0.2f°", curserial->ptz_state.x_coordinate, curserial->ptz_state.y_coordinate); + DebugLog(0, szbuf, 'I'); + break; + } + } + curserial->SerialCmdidx = -1; + break; case 0x15: if (0xFF == rtumsg.MsgData[6]) { @@ -2233,7 +1813,7 @@ int FindNextCameraPhotoCommand(SIO_PARAM_SERIAL_DEF *pPortParam) } switch (cmdno) { - case 0:/* 下发拍照指令*/ + case TAKE_PHOTO:/* 下发拍照指令*/ if (lcurtime - pPortParam->FirstCmdTimeCnt < 3800) return -1; if ((lcurtime - pPortParam->FirstCmdTimeCnt > 3 * 35 * 1000) || (lcurtime - pPortParam->FirstCmdTimeCnt < 0)) @@ -2260,7 +1840,7 @@ int FindNextCameraPhotoCommand(SIO_PARAM_SERIAL_DEF *pPortParam) imagesize = srdt.bImageSize; break; - case 10000: /* 下发设置串口波特率命令*/ + case SET_BAUD: /* 下发设置串口波特率命令*/ #if 0 switch (devparam[devidx].baudrate) { @@ -2308,7 +1888,7 @@ int FindNextCameraPhotoCommand(SIO_PARAM_SERIAL_DEF *pPortParam) packetsize = (uint16_t)MAX_PHOTO_FRAME_LEN; break; - case 10005: /* 关闭功能*/ + case STOP_CMD: /* 关闭功能*/ //Gm_CtrlPtzCmd(1, P_MOVE_LEFT); //sleep(2); Gm_CtrlPtzCmd(pPortParam, Cmd_Cancel); @@ -2317,25 +1897,25 @@ int FindNextCameraPhotoCommand(SIO_PARAM_SERIAL_DEF *pPortParam) srdt.iLastGetPhotoNo = -1; //sleep(20); return 1; - case 10006: /* 自动扫描功能控制(1/0 打开/关闭该功能)*/ + case AUTO_SCAN: /* 自动扫描功能控制(1/0 打开/关闭该功能)*/ Gm_CtrlPtzCmd(pPortParam, P_Auto_Scan); usleep(100000); pPortParam->SerialCmdidx = srdt.iLastGetPhotoNo; srdt.iLastGetPhotoNo = -1; return 1; - case 10007: /* 光圈缩小(1 有效)*/ + case IRIS_CLOSE: /* 光圈缩小(1 有效)*/ Gm_CtrlPtzCmd(pPortParam, P_IRIS_CLOSE); usleep(100000); pPortParam->SerialCmdidx = srdt.iLastGetPhotoNo; srdt.iLastGetPhotoNo = -1; return 1; - case 10008: /* 光圈放大(1 有效)*/ + case IRIS_OPEN: /* 光圈放大(1 有效)*/ Gm_CtrlPtzCmd(pPortParam, P_IRIS_OPEN); usleep(100000); pPortParam->SerialCmdidx = srdt.iLastGetPhotoNo; srdt.iLastGetPhotoNo = -1; return 1; - case 10009: /* 近距离聚焦(1 有效)*/ + case FOCUS_NEAR: /* 近距离聚焦(1 有效)*/ Gm_CtrlPtzCmd(pPortParam, P_FOCUS_NEAR); usleep(500000); Gm_CtrlPtzCmd(pPortParam, Cmd_Cancel); @@ -2343,7 +1923,7 @@ int FindNextCameraPhotoCommand(SIO_PARAM_SERIAL_DEF *pPortParam) pPortParam->SerialCmdidx = srdt.iLastGetPhotoNo; srdt.iLastGetPhotoNo = -1; return 1; - case 10010: /* 远距离聚焦(1 有效)*/ + case FOCUS_FAR: /* 远距离聚焦(1 有效)*/ Gm_CtrlPtzCmd(pPortParam, P_FOCUS_FAR); usleep(500000); Gm_CtrlPtzCmd(pPortParam, Cmd_Cancel); @@ -2351,7 +1931,7 @@ int FindNextCameraPhotoCommand(SIO_PARAM_SERIAL_DEF *pPortParam) pPortParam->SerialCmdidx = srdt.iLastGetPhotoNo; srdt.iLastGetPhotoNo = -1; return 1; - case 10011: /* 远离物体(1 有效)*/ + case ZOOM_WIDE: /* 远离物体(1 有效)*/ Gm_CtrlPtzCmd(pPortParam, P_ZOOM_WIDE); usleep(500000); Gm_CtrlPtzCmd(pPortParam, Cmd_Cancel); @@ -2359,7 +1939,7 @@ int FindNextCameraPhotoCommand(SIO_PARAM_SERIAL_DEF *pPortParam) pPortParam->SerialCmdidx = srdt.iLastGetPhotoNo; srdt.iLastGetPhotoNo = -1; return 1; - case 10012: /* 接近物体(1 有效)*/ + case ZOOM_TELE: /* 接近物体(1 有效)*/ Gm_CtrlPtzCmd(pPortParam, P_ZOOM_TELE); usleep(500000); Gm_CtrlPtzCmd(pPortParam, Cmd_Cancel); @@ -2367,7 +1947,7 @@ int FindNextCameraPhotoCommand(SIO_PARAM_SERIAL_DEF *pPortParam) pPortParam->SerialCmdidx = srdt.iLastGetPhotoNo; srdt.iLastGetPhotoNo = -1; return 1; - case 10013: /* 向下移动镜头(1 有效)*/ + case MOVE_DOWN: /* 向下移动镜头(1 有效)*/ Gm_CtrlPtzCmd(pPortParam, P_MOVE_DOWN); sleep(1); Gm_CtrlPtzCmd(pPortParam, Cmd_Cancel); @@ -2375,7 +1955,7 @@ int FindNextCameraPhotoCommand(SIO_PARAM_SERIAL_DEF *pPortParam) pPortParam->SerialCmdidx = srdt.iLastGetPhotoNo; srdt.iLastGetPhotoNo = -1; return 1; - case 10014: /* 向上移动镜头(1 有效)*/ + case MOVE_UP: /* 向上移动镜头(1 有效)*/ Gm_CtrlPtzCmd(pPortParam, P_MOVE_UP); sleep(1); Gm_CtrlPtzCmd(pPortParam, Cmd_Cancel); @@ -2383,7 +1963,7 @@ int FindNextCameraPhotoCommand(SIO_PARAM_SERIAL_DEF *pPortParam) pPortParam->SerialCmdidx = srdt.iLastGetPhotoNo; srdt.iLastGetPhotoNo = -1; return 1; - case 10015: /* 向左移动镜头(1 有效)*/ + case MOVE_LEFT: /* 向左移动镜头(1 有效)*/ Gm_CtrlPtzCmd(pPortParam, P_MOVE_LEFT); sleep(1); Gm_CtrlPtzCmd(pPortParam, Cmd_Cancel); @@ -2391,7 +1971,7 @@ int FindNextCameraPhotoCommand(SIO_PARAM_SERIAL_DEF *pPortParam) pPortParam->SerialCmdidx = srdt.iLastGetPhotoNo; srdt.iLastGetPhotoNo = -1; return 1; - case 10016: /* 向右移动镜头(1 有效)*/ + case MOVE_RIGHT: /* 向右移动镜头(1 有效)*/ Gm_CtrlPtzCmd(pPortParam, P_MOVE_RIGHT); sleep(1); Gm_CtrlPtzCmd(pPortParam, Cmd_Cancel); @@ -2399,9 +1979,10 @@ int FindNextCameraPhotoCommand(SIO_PARAM_SERIAL_DEF *pPortParam) pPortParam->SerialCmdidx = srdt.iLastGetPhotoNo; srdt.iLastGetPhotoNo = -1; return 1; - case 10017: /* 调用预置点*/ + case MOVE_PRESETNO: /* 调用预置点*/ //srdt.presetno = 2; Gm_CtrlPtzCmd(pPortParam, MOVE_TO_PRESETNO + srdt.presetno); +#if 0 sleep(2); if (0 == srdt.IsSleep) { @@ -2409,16 +1990,44 @@ int FindNextCameraPhotoCommand(SIO_PARAM_SERIAL_DEF *pPortParam) srdt.IsSleep++; return 1; } +#endif pPortParam->SerialCmdidx = srdt.iLastGetPhotoNo; srdt.iLastGetPhotoNo = -1; srdt.IsSleep = 0; return 1; - case 10018: /* 设置预置点*/ + case SAVE_PRESETNO: /* 设置预置点*/ Gm_CtrlPtzCmd(pPortParam, SET_PRESETNO + srdt.presetno); usleep(100000); pPortParam->SerialCmdidx = srdt.iLastGetPhotoNo; srdt.iLastGetPhotoNo = -1; return 1; + case NOTIFY_PTZ_CLOSE: /* 通知云台关闭电源*/ + if (pPortParam->sendptzstatecmd > 0) + { + pPortParam->SerialCmdidx = -2; + pPortParam->sendptzstatecmd = 0; + strcpy(szbuf, "云台未接或故障!结束通知!"); + DebugLog(0, szbuf, 'I'); + return -1; + } + cmdidx = 0xA0; + pPortParam->sendptzstatecmd++; + //pPortParam->SerialCmdidx = -1; + break; + case QUERY_PTZ_STATE: /* 查询云台状态信息*/ + if (pPortParam->sendptzstatecmd > 0) + { + pPortParam->SerialCmdidx = -2; + pPortParam->sendptzstatecmd = 0; + strcpy(szbuf, "云台未接或故障!结束查询!"); + DebugLog(0, szbuf, 'I'); + return -1; + } + pPortParam->sendptzstatecmd++; + cmdidx = 0x08; + //pPortParam->SerialCmdidx = -1; + break; + default: imagesize = 0xFF; packetsize = (uint16_t)pPortParam->SerialCmdidx; @@ -2832,13 +2441,23 @@ void MakeShxyProtocolPollCommand(int portno, uint8_t cmdidx) unsigned char CalLpc(unsigned char *msg, int len) { int i; - u_char retval = 0; + unsigned char retval = 0; for (i = 0; i < len; i++) retval += msg[i]; return retval; } +unsigned char BDXorCheck(unsigned char *msg, int len) +{ + int i; + unsigned char retval = 0; + + for (i = 0; i < len; i++) + retval ^= msg[i]; + return retval; +} + /*************************************************************** * 读上海欣影传感器协议数据 * ***************************************************************/ @@ -3068,6 +2687,8 @@ void ShxyProtocolDataProcess(int devno) switch (curserial->m_au8RecvBuf[j]) { case 1: /*温度*/ + if(devparam[devno].ProtocolIdx == WIND_PROTOCOL) + break; if ((fvalue < -60) || (fvalue > 100)) { frnb = (GeneratingRandomNumber() % 101 - 50) / 1000.0; @@ -3077,8 +2698,8 @@ void ShxyProtocolDataProcess(int devno) } else { - pPortParam->aiValue[AirTempNo].EuValue = fvalue;/*pPortParam->aiValue[0].AiParam.fFactor + pPortParam->aiValue[0].AiParam.EuValueDelta;*/ - weatherpntmsg[AirTempNo].EuValue = fvalue;/*weatherpntmsg[AirTempNo].AiParam.fFactor + weatherpntmsg[AirTempNo].AiParam.EuValueDelta;*/ + pPortParam->aiValue[AirTempNo].EuValue = fvalue; + weatherpntmsg[AirTempNo].EuValue = fvalue; } pPortParam->aiValue[AirTempNo].AiState = SER_SAMPLE; weatherpntmsg[AirTempNo].AiState = SER_SAMPLE; @@ -3086,10 +2707,12 @@ void ShxyProtocolDataProcess(int devno) //if ((gDisSunRain & 0x80) == 0x80) { sprintf(szbuf, "ID:%d 温度:%0.3f ", devparam[devno].devaddr, fvalue); - //DebugLog(devparam[devno].commid, szbuf, 'V'); + DebugLog(devparam[devno].commid, szbuf, 'V'); } break; case 2: /*气压*/ + if(devparam[devno].ProtocolIdx == WIND_PROTOCOL) + break; if ((fvalue < 550) || (fvalue > 1060)) { frnb = (GeneratingRandomNumber() % 41 - 20) / 10000.0; @@ -3098,19 +2721,21 @@ void ShxyProtocolDataProcess(int devno) } else { - pPortParam->aiValue[AtmosNo].EuValue = fvalue;/*pPortParam->aiValue[5].AiParam.fFactor + pPortParam->aiValue[5].AiParam.EuValueDelta;*/ - weatherpntmsg[AtmosNo].EuValue = fvalue;/*weatherpntmsg[AtmosNo].AiParam.fFactor + weatherpntmsg[AtmosNo].AiParam.EuValueDelta;*/ + pPortParam->aiValue[AtmosNo].EuValue = fvalue; + weatherpntmsg[AtmosNo].EuValue = fvalue; } pPortParam->aiValue[AtmosNo].AiState = SER_SAMPLE; weatherpntmsg[AtmosNo].AiState = SER_SAMPLE; //g_SelfTest.SensorsFault |= (0x10); //if ((gDisSunRain & 0x80) == 0x80) { - sprintf(szbuf, "%s气压:%0.3f ", szbuf, fvalue); - //DebugLog(devparam[devno].commid, szbuf, 'V'); + sprintf(szbuf, "气压:%0.3f ", fvalue); + DebugLog(devparam[devno].commid, szbuf, 'V'); } break; case 3: /*湿度*/ + if(devparam[devno].ProtocolIdx == WIND_PROTOCOL) + break; if ((fvalue < 0) || (fvalue > 100)) { frnb = (GeneratingRandomNumber() % 41 - 20) / 1000.0; @@ -3127,9 +2752,8 @@ void ShxyProtocolDataProcess(int devno) //g_SelfTest.SensorsFault |= (0x02); //if ((gDisSunRain & 0x80) == 0x80) { - sprintf(szbuf, "%s湿度:%0.3f ", szbuf, fvalue); - if(datanum < 6) - DebugLog(devparam[devno].commid, szbuf, 'V'); + sprintf(szbuf, "湿度:%0.3f ", fvalue); + DebugLog(devparam[devno].commid, szbuf, 'V'); } break; case 4: /*雨量*/ @@ -3149,9 +2773,8 @@ void ShxyProtocolDataProcess(int devno) //g_SelfTest.SensorsFault |= (0x02); //if ((gDisSunRain & 0x80) == 0x80) { - sprintf(szbuf, "%s雨量:%0.3f ", szbuf, fvalue); - if(datanum < 7) - DebugLog(devparam[devno].commid, szbuf, 'V'); + sprintf(szbuf, "雨量:%0.3f ", fvalue); + DebugLog(devparam[devno].commid, szbuf, 'V'); } break; case 5: /*日照*/ @@ -3169,7 +2792,7 @@ void ShxyProtocolDataProcess(int devno) pPortParam->aiValue[OpticalRadiationNo].AiState = SER_SAMPLE; weatherpntmsg[OpticalRadiationNo].AiState = SER_SAMPLE; { - sprintf(szbuf, "%s日照:%0.3f ", szbuf, fvalue); + sprintf(szbuf, "日照:%0.3f ", fvalue); DebugLog(devparam[devno].commid, szbuf, 'V'); } break; @@ -3638,13 +3261,13 @@ int GM_IsCloseCamera(SIO_PARAM_SERIAL_DEF *pPortParam) lctime = get_msec(); memset(buf, 0, sizeof(buf)); - if (-1 == pPortParam->SerialCmdidx) + if (0 > pPortParam->SerialCmdidx) { if ((SER_STARTSAMPLE == pPortParam->image.state) || (SER_SAMPLE == pPortParam->image.state)) pPortParam->image.state = SER_SAMPLEFAIL; else if (PHOTO_SAVE_SUCC == pPortParam->image.state) pPortParam->image.state = PHOTO_SAVE_SUCC; - strcpy(buf, "通道1摄像机使用完毕!可以关闭摄像机电源!"); + strcpy(buf, "摄像机使用完毕!可以关闭摄像机电源!"); DebugLog(0, buf, 'I'); memset(&serialport[0].image, 0, sizeof(PHOTO_DEF)); memmove((void *)&serialport[0].image, (void*)&pPortParam->image, sizeof(PHOTO_DEF)); @@ -3677,14 +3300,17 @@ void GM_CameraSerialComRecv(SIO_PARAM_SERIAL_DEF *pPortParam) recvlen = read(pPortParam->fd, &recvbuf[i], sizeof(recvbuf)-i);/* 在串口读取字符串 */ t1 = get_msec(); if(t1-t0 >= 350) - break; + { + i += recvlen; + break; + } } recvlen = i; if (recvlen < 1) return; #if 1 - sprintf(buf, "收到Camera, %d字节数据:", recvlen); + sprintf(buf, "收到BD, %d字节数据:", recvlen); BytestreamLOG(0, buf, recvbuf, recvlen, 'I'); #endif @@ -3695,9 +3321,9 @@ int GM_CameraSerialTimer(SIO_PARAM_SERIAL_DEF *pPortParam) { int flag = -1; - GM_CameraSerialComRecv(pPortParam); - Gm_FindCameraCommand(pPortParam); //GM_CameraSerialComRecv(pPortParam); + Gm_FindCameraCommand(pPortParam); + GM_CameraSerialComRecv(pPortParam); flag = GM_IsCloseCamera(pPortParam); return flag; } @@ -3729,11 +3355,11 @@ int GM_StartSerialCameraPhoto(int phototime, unsigned char channel, int cmdidx, #if 1 memset(szbuf, 0, sizeof(szbuf)); srdt.iLastGetPhotoNo = -1; - if (0 == cmdidx) + if (TAKE_PHOTO == cmdidx) cameraport->image.state = SER_STARTSAMPLE; - if ((0 == cmdidx) && (srdt.presetno > 0)) + if ((TAKE_PHOTO == cmdidx) && (srdt.presetno > 0)) { - cameraport->SerialCmdidx = 10017; + cameraport->SerialCmdidx = MOVE_PRESETNO; srdt.iLastGetPhotoNo = cmdidx; } else @@ -3774,7 +3400,7 @@ int GM_StartSerialCameraPhoto(int phototime, unsigned char channel, int cmdidx, { //LOGE("12V state=%d", getInt(CMD_SET_12V_EN_STATE)); DebugLog(8, "退出操作摄像机流程!", 'V'); - sleep(3); + //sleep(3); break; } } @@ -3800,6 +3426,542 @@ int CameraPhotoCmd(int phototime, unsigned char channel, int cmdidx, unsigned ch pthread_mutex_unlock(&camera_mutex); // 解锁 return flag; } + +int QueryPtzState(PTZ_STATE *ptz_state, int cmdidx, const char *serfile, unsigned int baud, int addr) +{ + pthread_mutex_lock(&camera_mutex); + int flag = 0; + char szbuf[128], logbuf[128]; + SIO_PARAM_SERIAL_DEF *cameraport=NULL; + + if(NULL == ptz_state) + return -1; + if((NOTIFY_PTZ_CLOSE == cmdidx) || (QUERY_PTZ_STATE == cmdidx)) + ; + else + return -1; + cameraport = (SIO_PARAM_SERIAL_DEF*)malloc(sizeof(SIO_PARAM_SERIAL_DEF)); + + cameraport->cameraaddr = addr; + cameraport->Retry = 0; + cameraport->RetryTime = 1000; + cameraport->WaitTime = 0; + cameraport->m_iRevStatus = 0; + cameraport->m_iRecvLen = 0; + cameraport->m_iNeedRevLength = 0; + cameraport->fd = -1; + memset(cameraport->m_au8RecvBuf, 0, RECVDATA_MAXLENTH); // 接收数据缓存区 + ClearCameraCmdFormPollCmdBuf(cameraport); + + flag = Gm_OpenCameraSerial(cameraport, serfile, baud); + +#if 1 + memset(szbuf, 0, sizeof(szbuf)); + srdt.iLastGetPhotoNo = -1; + cameraport->SerialCmdidx = cmdidx; + cameraport->FirstCmdTimeCnt = get_msec(); + cameraport->sendptzstatecmd = 0; +#endif + if(-1 == flag) + { + if(NULL != cameraport) + { + free(cameraport); + cameraport = NULL; + } + return -1; + } + + if (0x00 == flag) + { + sprintf(szbuf, "云台状态查询启动串口定时器!"); + DebugLog(8, szbuf, 'I'); + for (;;) + { + usleep(10); + //LOGW("polltime=%ldms", get_msec()-polltime); + //polltime = get_msec(); + flag = GM_CameraSerialTimer(cameraport); + if (flag < 0) + { + //LOGE("12V state=%d", getInt(CMD_SET_12V_EN_STATE)); + DebugLog(8, "退出查询云台状态流程!", 'V'); + memmove((void*)ptz_state, &cameraport->ptz_state, sizeof(PTZ_STATE)); + if(flag == -2) + flag = -1; + else + flag = 0; + //sleep(3); + break; + } + } + } + if(NULL != cameraport) + { + free(cameraport); + cameraport = NULL; + } + pthread_mutex_unlock(&camera_mutex); // 解锁 + return flag; +} + +int Query_BDGNSS_Data(BD_GNSS_DATA *BD_data, int samptime, const char *serfile, unsigned int baud) +{ + pthread_mutex_lock(&bd_mutex); + int flag = 0; + char szbuf[128], logbuf[128]; + SIO_PARAM_SERIAL_DEF *cameraport=NULL; + + if(NULL == BD_data) + return -1; + if(samptime < 5) + samptime = 5; + cameraport = (SIO_PARAM_SERIAL_DEF*)malloc(sizeof(SIO_PARAM_SERIAL_DEF)); + + cameraport->Retry = 0; + cameraport->RetryTime = 1000; + cameraport->WaitTime = 0; + cameraport->m_iRevStatus = 0; + cameraport->m_iRecvLen = 0; + cameraport->m_iNeedRevLength = 0; + cameraport->fd = -1; + memset(cameraport->m_au8RecvBuf, 0, RECVDATA_MAXLENTH); // 接收数据缓存区 + ClearCameraCmdFormPollCmdBuf(cameraport); + + flag = Gm_OpenCameraSerial(cameraport, serfile, baud); + +#if 1 + memset(szbuf, 0, sizeof(szbuf)); + srdt.iLastGetPhotoNo = -1; + cameraport->SerialCmdidx = -1; + cameraport->FirstCmdTimeCnt = get_msec(); +#endif + if(-1 == flag) + { + if(NULL != cameraport) + { + free(cameraport); + cameraport = NULL; + } + return -1; + } + + if (0x00 == flag) + { + sprintf(szbuf, "北斗定位数据查询启动串口定时器!"); + DebugLog(8, szbuf, 'I'); + for (;;) + { + usleep(10); + //LOGW("polltime=%ldms", get_msec()-polltime); + //polltime = get_msec(); + flag = GM_BdSerialTimer(cameraport); + if(get_msec() - cameraport->FirstCmdTimeCnt > samptime*1000) + { + DebugLog(8, "退出查询北斗定位数据流程!", 'V'); + memmove((void*)BD_data, &cameraport->bd_data, sizeof(BD_GNSS_DATA)); + break; + } + } + } + if(NULL != cameraport) + { + free(cameraport); + cameraport = NULL; + } + pthread_mutex_unlock(&bd_mutex); // 解锁 + return flag; +} + +int GM_BdSerialTimer(SIO_PARAM_SERIAL_DEF *pPortParam) +{ + int flag = 0; + + GM_BdSerialComRecv(pPortParam); + return flag; +} + +void GM_BdSerialComRecv(SIO_PARAM_SERIAL_DEF *pPortParam) +{ + int i, recvlen; + u_char recvbuf[RECVDATA_MAXLENTH]; + char buf[RECVDATA_MAXLENTH+256]; + int64_t t0, t1; + + t0 = get_msec(); + + memset(recvbuf, 0, sizeof(recvbuf)); + if (pPortParam->fd <= 0) + return; + i=0; + recvlen = 0; + memset(recvbuf, 0, sizeof(recvbuf)); + for(;;) + { + i += recvlen; + recvlen = read(pPortParam->fd, &recvbuf[i], sizeof(recvbuf)-i);/* 在串口读取字符串 */ + t1 = get_msec(); + if(t1-t0 >= 350) + break; + } + + recvlen = i; + if (recvlen < 1) + return; +#if 1 + sprintf(buf, "收到BD, %d字节数据:%s", recvlen, recvbuf); + DebugLog(0, (char*)recvbuf, 'I'); +#endif + + BdRecvData(pPortParam, recvbuf, recvlen); +} + +void BdRecvData(SIO_PARAM_SERIAL_DEF *pPortParam, u_char *buf, int len) +{ + int i; + unsigned char bdxor=0, srcxor=0; + + for (i = 0; i < len; i++) + { + switch (pPortParam->m_iRevStatus) + { + case 0: // 搜索起始符 '$' + pPortParam->m_iRecvLen = 0; + memset(pPortParam->m_au8RecvBuf, 0,sizeof(pPortParam->m_au8RecvBuf)); + if ('$' == buf[i]) + { + pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i]; + pPortParam->m_iRevStatus = 1; // 进入数据接收状态 + } + break; + case 1: // 接收数据直到 '*' + if (pPortParam->m_iRecvLen >= RECVDATA_MAXLENTH) + { + // 缓冲区溢出,重置状态 + pPortParam->m_iRevStatus = 0; + pPortParam->m_iRecvLen = 0; + break; + } + pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i]; + + if (buf[i] == '*') + { + pPortParam->m_iRevStatus = 2; // 进入校验码接收状态 + } + break; + case 2: // 接收校验码(2字节十六进制)和 + if (pPortParam->m_iRecvLen >= RECVDATA_MAXLENTH) + { + // 缓冲区溢出,重置状态 + pPortParam->m_iRevStatus = 0; + pPortParam->m_iRecvLen = 0; + break; + } + pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i]; + + // 检测到换行符(0x0A),检查前一个字符是否为回车符(0x0D) + if (buf[i] == 0x0A) + { + if (pPortParam->m_iRecvLen >= 5 && + pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen - 2] == 0x0D) + { + // 提取校验码(*后的两个字符) + char hex_str[3] = { + (char)pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen - 4], + (char)pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen - 3], + '\0' + }; + srcxor = (uint8_t)strtol(hex_str, NULL, 16); + + // 计算校验值(从$后的第一个字符到*前的字符) + uint8_t calc_xor = BDXorCheck(&pPortParam->m_au8RecvBuf[1],pPortParam->m_iRecvLen - 6);// 长度 = 总长度 - ($ + *HH + \r\n) + + if (srcxor == calc_xor) + { + BD_NMEA0183_PortDataProcess(pPortParam); + pPortParam->RevCmdFlag = 1; + } + // 重置状态,准备接收下一帧 + pPortParam->m_iRevStatus = 0; + pPortParam->m_iRecvLen = 0; + } + else + { + // 格式错误,丢弃数据 + pPortParam->m_iRevStatus = 0; + pPortParam->m_iRecvLen = 0; + } + } + break; + case 255:// 错误接收数据 + default: + if (buf[i] == '$') + { + pPortParam->m_iRevStatus = 1; + pPortParam->m_iRecvLen = 1; + pPortParam->m_au8RecvBuf[0] = buf[i]; + } + else + { + pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i]; + if (pPortParam->m_iRecvLen > 200) + { + pPortParam->m_iRecvLen = 0; + } + } + break; + } + } +} + +/* +$BDRMC,023656.00,A,2240.61563,N,11359.86512,E,0.16,,140324,,,A,V*2C +$BDVTG,,,,,0.16,N,0.30,K,A*2F +$BDGGA,023656.00,2240.61563,N,11359.86512,E,1,23,0.7,96.53,M,-3.52,M,,*5B +$BDGSA,A,3,01,02,03,04,05,06,07,09,10,16,19,20,1.0,0.7,0.8,4*30 +$BDGSV,6,1,23,01,45,125,38,02,46,235,40,03,61,189,46,04,32,112,37,1*7B +$BDGLL,2240.61563,N,11359.86512,E,023656.00,A,A*78 +$BDZDA,023656.00,14,03,2024,00,00*71 +$GPTXT,01,01,01,ANTENNA OPEN*25 + GLL:经度、纬度、UTC 时间 +GSA:北斗接收机操作模式,定位使用的卫星,DOP 值 +GSV:可见北斗卫星信息、仰角、方位角、信噪比(SNR) +RMC:时间、日期、位置、速度 +VTG:地面速度信息 +ZDA: 时间、日期 +TXT:用于天线状态检测 + */ +void BD_NMEA0183_PortDataProcess(SIO_PARAM_SERIAL_DEF *curserial) +{ + BD_NMEA0183_PROC_FUNC bd_nmea0183_call[] = { + {"$BDRMC",BD_get_BDRMC_data},/* 时间、日期、位置、速度*/ + {"$BDVTG",NULL},/* 地面速度信息*/ + {"$BDGGA",NULL},/* 时间、位置、定位类型*/ + {"$BDGSA",NULL},/* 北斗接收机操作模式,定位使用的卫星,DOP 值 */ + {"$BDGSV",NULL},/* 可见北斗卫星信息、仰角、方位角、信噪比(SNR)*/ + {"$BDGLL",NULL},/* 经度、纬度、UTC 时间*/ + {"$BDZDA",NULL},/* 时间、日期 */ + {"$GPTXT",NULL},/* 用于天线状态检测*/ + };/* irows*/ + int i=0, irows; + char szbuf[512]; + //char *cmd=NULL, *sourestr=NULL; + //RTUMSG rtumsg; + + if(NULL == curserial) + return; + irows = sizeof(bd_nmea0183_call)/sizeof(BD_NMEA0183_PROC_FUNC); + memset(szbuf, 0, sizeof(szbuf)); + //sprintf(szbuf, "rows = %d", irows); + DebugLog(0, (char*)curserial->m_au8RecvBuf, 'I'); + +#if 0 + memset((void*)rtumsg.MsgData, 0, sizeof(rtumsg.MsgData)); + memcpy((void*)rtumsg.MsgData, (void*)curserial->m_au8RecvBuf, curserial->m_iRecvLen); + rtumsg.MsgLen = curserial->m_iRecvLen; + /* 析出关键字符串*/ + cmd = (char *)rtumsg.MsgData; + sourestr = strstr((char *)rtumsg.MsgData, ","); + *sourestr = 0; + sprintf(szbuf, "cmd_len = %d, cmd:%s", strlen(cmd), cmd); + DebugLog(0, szbuf, 'I'); +#endif + + for(i=0; im_au8RecvBuf, bd_nmea0183_call[i].cmd_name)) + { + sprintf(szbuf, "cmd_name[%d]:%s", i, bd_nmea0183_call[i].cmd_name); + DebugLog(0, szbuf, 'I'); + if(NULL != bd_nmea0183_call[i].recv_process) + bd_nmea0183_call[i].recv_process(curserial); + break; + } + } + if(i >= irows) + return; +} + +int BD_get_BDRMC_data(SIO_PARAM_SERIAL_DEF *curserial) +{ + const int UTC_TIME = 1; + const int STATUS = 2; + const int LAT = 3; + const int ULAT = 4; + const int LON = 5; + const int ULON = 6; + const int DATE = 9; + double dvalue; + int total_fields=0, ivalue; + char **result = NULL; + char buffer[128]; // 存储格式化时间的缓冲区 + + if(NULL == curserial) + return -1; + /* + 1 $--RMC 字符串 消息 ID,RMC 语句头,’--‘为系统标识 + 2 UTCtime hhmmss.ss 当前定位的 UTC 时间 + 3 status 字符串 位置有效标志。 V=接收机警告,数据无效 A=数据有效 + 4 lat ddmm.mmmmm 纬度,前 2 字符表示度,后面的字符表示分 + 5 uLat 字符 纬度方向:N-北,S-南 + 6 lon dddmm.mmmmm 经度,前 3 字符表示度,后面的字符表示分 + 7 uLon 字符 经度方向:E-东,W-西 + 8 spd 数值 对地速度,单位为节 + 9 cog 数值 对地真航向,单位为度 + 10 date ddmmyy 日期(dd 为日,mm 为月,yy 为年) + 11 mv 数值 磁偏角,单位为度。固定为空 + 12 mvE 字符 磁偏角方向:E-东,W-西。固定为空 + 13 mode 字符 定位模式标志(备注[1]) + 14 navStatus 字符 导航状态标示符(V 表示系统不输出导航状态信息) 仅 NMEA 4.1 及以上版本有效 + 15 CS 16 进制数值 校验和,$和*之间(不包括$和*)所有字符的异或结果 + 16 字符 回车与换行符*/ + + result = BD_NMEA0183_SplitString((char *)curserial->m_au8RecvBuf, &total_fields); + if(NULL == result) + return -1; + + dvalue = ::atof(result[UTC_TIME]); + curserial->bd_data.UTC_time.tm_sec = (int)dvalue%100; + curserial->bd_data.UTC_time.tm_min = (int)dvalue/100%100; + curserial->bd_data.UTC_time.tm_hour = (int)dvalue/10000; + curserial->bd_data.ms_time = (dvalue - ((int)dvalue/1))*1000; + + curserial->bd_data.status = result[STATUS][0]; + dvalue = ::atof(result[LAT]); + curserial->bd_data.lat = ((int)dvalue/100)+(dvalue - ((int)dvalue/100*100))/60; + curserial->bd_data.uLat = result[ULAT][0]; + dvalue = ::atof(result[LON]); + curserial->bd_data.lon = ((int)dvalue/100)+(dvalue - ((int)dvalue/100*100))/60; + curserial->bd_data.uLon = result[ULON][0]; + + ivalue = ::atoi(result[DATE]); + ALOGD("%d", ivalue); + curserial->bd_data.UTC_time.tm_mday = ivalue/10000; + ALOGD("D:%d", curserial->bd_data.UTC_time.tm_mday); + curserial->bd_data.UTC_time.tm_mon = ivalue/100%100-1; + ALOGD("M:%d", curserial->bd_data.UTC_time.tm_mon); + curserial->bd_data.UTC_time.tm_year = ivalue%100+100; + ALOGD("Y:%d", curserial->bd_data.UTC_time.tm_year); + + ::memset(buffer, 0, sizeof(buffer)); + // 使用 strftime 格式化时间 + strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", &curserial->bd_data.UTC_time); + DebugLog(0, (char*)buffer, 'I'); + + ::sprintf(buffer, "ms:%d lat=%f ulat=%c", curserial->bd_data.ms_time, curserial->bd_data.lat, curserial->bd_data.uLat); + DebugLog(0, (char*)buffer, 'I'); + ::sprintf(buffer, "lon=%f ulon=%c, status=%c", curserial->bd_data.lon, curserial->bd_data.uLon, curserial->bd_data.status); + DebugLog(0, (char*)buffer, 'I'); + + // 释放内存 + for (int i = 0; i < total_fields; ++i) free(result[i]); + free(result); + + return 0; +} + +char** BD_NMEA0183_SplitString(char *str, int *total_fields) +{ + int max_fields, field_count = 0; + char **fields = NULL, **new_fields = NULL, **result = NULL; + char *copy = NULL, *p = NULL; + char szbuf[128]; + + if(NULL == str) + return NULL; + if(NULL == total_fields) + return NULL; + + // 创建可修改的副本 + copy = strdup(str); + memset(szbuf, 0, sizeof(szbuf)); + if (!copy) + { + sprintf(szbuf, "内存分配失败\n"); + DebugLog(0, szbuf, 'E'); + return NULL; + } + + // 初始字段数组大小 + max_fields = MAX_FIELDS_NUM; + fields = (char**)malloc(max_fields * sizeof(char *)); + if (!fields) { + free(copy); + sprintf(szbuf, "fields 内存分配失败\n"); + DebugLog(0, szbuf, 'E'); + return NULL; + } + + field_count = 0; + fields[field_count] = copy; // 第一个字段起始 + + // 遍历字符串分割字段 + for (p = copy; *p; ++p) + { + if (*p == ',') + { + *p = '\0'; // 结束当前字段 + field_count++; + + // 动态扩展数组 + if (field_count >= max_fields) { + max_fields *= 2; + new_fields = (char**)realloc(fields, max_fields * sizeof(char *)); + if (!new_fields) { + free(fields); + free(copy); + sprintf(szbuf, "new_fields 内存分配失败\n"); + DebugLog(0, szbuf, 'E'); + return NULL; + } + fields = new_fields; + } + fields[field_count] = p + 1; // 下一字段起始 + } + } + + *total_fields = field_count + 1; // 总字段数 + + // 复制字段到独立内存 + result = (char **)malloc((*total_fields) * sizeof(char *)); + if (!result) + { + free(fields); + free(copy); + sprintf(szbuf, "result 内存分配失败\n"); + DebugLog(0, szbuf, 'E'); + return NULL; + } + + for (int i = 0; i < *total_fields; ++i) { + result[i] = strdup(fields[i]); + if (!result[i]) { + // 释放已分配内存 + for (int j = 0; j < i; ++j) free(result[j]); + free(result); + free(fields); + free(copy); + sprintf(szbuf, "result 字段复制失败\n"); + DebugLog(0, szbuf, 'E'); + return NULL; + } + } + + // 输出结果到日志 + for (int i = 0; i < *total_fields; ++i) + { + sprintf(szbuf, "字段 %2d: %s\n", i + 1, result[i]); + DebugLog(0, szbuf, 'I'); + } + + // 释放内存 + //for (int i = 0; i < total_fields; ++i) free(result[i]); + //free(result); + free(fields); + free(copy); + + return result; +} /* 串口启动接口函数 结束*/ /* 数据和图片采集数据返回函数 开始*/ diff --git a/app/src/main/cpp/SensorsProtocol.h b/app/src/main/cpp/SensorsProtocol.h index f21f40a0..c2d18211 100644 --- a/app/src/main/cpp/SensorsProtocol.h +++ b/app/src/main/cpp/SensorsProtocol.h @@ -27,6 +27,7 @@ #define IOT_PARAM_WRITE 0xAE #define IOT_PARAM_READ 0xAF +#define MAX_FIELDS_NUM 20 /* BD_NMEA0183单组字符串数据内含数据最大数量*/ #define MAX_SERIAL_DEV_NUM 25 /* 最大接串口传感器数量*/ #define MAX_SERIAL_PORT_NUM 5 #define MAX_DEV_VALUE_NUM 12 /* 一台装置最大的采样值数量*/ @@ -39,6 +40,7 @@ #define PELCO_D_PROTOCOL 6 /* 摄像机Pelco_D协议序号*/ #define SERIALCAMERA_PROTOCOL 8 /* 串口摄像机协议序号*/ #define MUTIWEATHER_PROTOCOL 9 /*多合一气象*/ +#define NMEA0183_PROTOCOL 10 /* 单一北斗NMEA0183标准协议*/ #define RESERVE2_PROTOCOL 17 /* 备用2协议序号*/ #define RESERVE4_PROTOCOL 19 /* 备用4协议序号*/ #define RESERVE5_PROTOCOL 20 /* 备用5协议序号*/ @@ -83,9 +85,9 @@ #define P_IRIS_OPEN 0x04000000 /* 光圈放大(1 有效)*/ #define P_FOCUS_NEAR 0x02000000 /* 近距离聚焦(1 有效)*/ #define P_FOCUS_FAR 0x01000000 /* 远距离聚焦(1 有效)*/ -#define P_ZOOM_WIDE 0x00400000 /* 远离物体(1 有效)*/ +#define P_ZOOM_WIDE 0x00400000 /* 远离物体(1 有效)*/ #define P_ZOOM_TELE 0x00200000 /* 接近物体(1 有效)*/ -#define P_MOVE_DOWN 0x0010001f /* 向下移动镜头(1 有效)*/ +#define P_MOVE_DOWN 0x0010001f /* 向下移动镜头(1 有效)*/ #define P_MOVE_UP 0x0008001f /* 向上移动镜头(1 有效)*/ #define P_MOVE_LEFT 0x00041f00 /* 向左移动镜头(1 有效)*/ #define P_MOVE_RIGHT 0x00021f00 /* 向右移动镜头(1 有效)*/ @@ -95,10 +97,10 @@ #define D_IRIS_CLOSE 0x04000000 /* 光圈缩小(1 有效)*/ #define D_IRIS_OPEN 0x02000000 /* 光圈放大(1 有效)*/ #define D_FOCUS_NEAR 0x01000000 /* 近距离聚焦(1 有效)*/ -#define D_FOCUS_FAR 0x00800000 /* 远距离聚焦(1 有效)*/ -#define D_ZOOM_WIDE 0x00400000 /* 远离物体(1 有效)*/ -#define D_ZOOM_TELE 0x00200000 /* 接近物体(1 有效)*/ -#define D_MOVE_DOWN 0x0010002d /* 向下移动镜头(1 有效)*/ +#define D_FOCUS_FAR 0x00800000 /* 远距离聚焦(1 有效)*/ +#define D_ZOOM_WIDE 0x00400000 /* 远离物体(1 有效)*/ +#define D_ZOOM_TELE 0x00200000 /* 接近物体(1 有效)*/ +#define D_MOVE_DOWN 0x0010002d /* 向下移动镜头(1 有效)*/ #define D_MOVE_UP 0x0008002d /* 向上移动镜头(1 有效)*/ #define D_MOVE_LEFT 0x00042d00 /* 向左移动镜头(1 有效)*/ #define D_MOVE_RIGHT 0x00022d00 /* 向右移动镜头(1 有效)*/ @@ -106,10 +108,10 @@ #define D_OPEN_MODULE_POWER 0x0009000C /* 打开机芯电源(1 有效)*/ /* 摄像机下发命令宏定义*/ -#define Take_Photo 0 /* 拍照*/ -#define Stop_Baud 10000 /* 设置球机波特率*/ -#define Stop_Cmd 10005 /* 取消或停止指令*/ -#define Auto_Scan 10006 /* 自动扫描功能控制(1/0 打开/关闭该功能)*/ +#define TAKE_PHOTO 20000 /* 拍照*/ +#define SET_BAUD 10000 /* 设置球机波特率*/ +#define STOP_CMD 10005 /* 取消或停止指令*/ +#define AUTO_SCAN 10006 /* 自动扫描功能控制(1/0 打开/关闭该功能)*/ #define IRIS_CLOSE 10007 /* 光圈缩小(1 有效)*/ #define IRIS_OPEN 10008 /* 光圈放大(1 有效)*/ #define FOCUS_NEAR 10009 /* 近距离聚焦(1 有效)*/ @@ -124,8 +126,8 @@ #define SAVE_PRESETNO 10018 // 设置预置点 #define OPEN_TOTAL 10019 /* 打开总电源(1 有效)*/ #define OPEN_MODULE_POWER 10020 /* 打开机芯电源(1 有效)*/ -#define CLOSE_TOTAL 10040 /* 关闭总电源*/ - +#define NOTIFY_PTZ_CLOSE 10021 // 通知云台关闭 +#define QUERY_PTZ_STATE 10022 // 查询云台状态 #define SPEED_DOME_CAMERA 0 /* 球机摄像机*/ #define SERIAL_CAMERA 2 /* 串口摄像机a*/ @@ -216,6 +218,48 @@ typedef struct uint8_t Phase; /* 传感器所安装相别,指拉力和倾角11表示A1....*/ } SERIAL_PARAM; +// 云台状态数据 +typedef struct +{ + uint8_t ptz_process; /* 云台所处过程(1:自检状态;2:调用预置点;3:一般状态;)*/ + uint8_t ptz_status; /* 云台当前状态值(0:停止;1:运动;2:机芯未上电;其他:其他错误*/ + int presetno; /* 云台所处预置点值*/ + float x_coordinate; /* 云台所处位置水平方向坐标*/ + float y_coordinate; /* 云台所处位置垂直方向坐标*/ +} PTZ_STATE; +/* +$--RMC 字符串 消息 ID,RMC 语句头,’--‘为系统标识 +2 UTCtime hhmmss.ss 当前定位的 UTC 时间 +3 status 字符串 位置有效标志。 +V=接收机警告,数据无效 + A=数据有效 +4 lat ddmm.mmmmm 纬度,前 2 字符表示度,后面的字符表示分 +5 uLat 字符 纬度方向:N-北,S-南 +6 lon dddmm.mmmm + m +经度,前 3 字符表示度,后面的字符表示分 +7 uLon 字符 经度方向:E-东,W-西 +8 spd 数值 对地速度,单位为节 +9 cog 数值 对地真航向,单位为度 +10 date ddmmyy 日期(dd 为日,mm 为月,yy 为年) +11 mv 数值 磁偏角,单位为度。固定为空 +12 mvE 字符 磁偏角方向:E-东,W-西。固定为空 +13 mode 字符 定位模式标志(备注[1]) +14 navStatus 字符 导航状态标示符(V 表示系统不输出导航状态信息) +仅 NMEA 4.1 及以上版本有效 +15 CS 16 进制数值 校验和,$和*之间(不包括$和*)所有字符的异或结果*/ +// 北斗卫星数据 +typedef struct +{ + struct tm UTC_time; /* UTC时间*/ + int ms_time; /* 毫秒*/ + double lat; /* 纬度,原值(前 2 字符表示度,后面的字符表示分)转换后为° */ + char uLat; /* 纬度方向:N-北,S-南*/ + double lon; /* 经度,原值(前 3 字符表示度,后面的字符表示分)转换后为°*/ + char uLon; /* 经度'E'-东,'W'-西*/ + char status; /* 'A'=数据有效 其他字符表示数据无效*/ +} BD_GNSS_DATA; + typedef struct { int m_iRevStatus; /* */ @@ -237,16 +281,26 @@ typedef struct uint16_t ForceWaitCnt; /* 强制等待计数*/ uint8_t ReSendCmdFlag; /* 重发命令标志 */ uint8_t SendCmdFlag; /* 命令发送标志 */ - uint8_t RevCmdFlag; /* 命令正常接收标志*/ + uint8_t RevCmdFlag; /* 命令正常接收标志*/ //********************************************************** - int64_t lsendtime; /* 命令发送绝对时间计时(毫秒)*/ - int cameraaddr; /* 摄像机地址*/ + int64_t lsendtime; /* 命令发送绝对时间计时(毫秒)*/ + int cameraaddr; /* 摄像机地址*/ int SerialCmdidx; /* 正在使用的串口发送命令的命令序号(-1:表示没有命令发送) 摄像机使用命令序号存储*/ - PHOTO_DEF image; /* 临时存储图片数据*/ + PHOTO_DEF image; /* 临时存储图片数据*/ int64_t FirstCmdTimeCnt; /* 串口读取数据起始时间*/ + PTZ_STATE ptz_state; + int sendptzstatecmd; // 查询命令次数控制 + BD_GNSS_DATA bd_data; } SIO_PARAM_SERIAL_DEF; +typedef const struct +{ + //char *account; // 命令说明 + char *cmd_name; // 命令名称 + int (*recv_process)(SIO_PARAM_SERIAL_DEF *); /* urc数据处理*/ +}BD_NMEA0183_PROC_FUNC; + //串口相关装置所有参数集中定义 typedef struct { @@ -474,6 +528,24 @@ int GM_IsCloseCamera(SIO_PARAM_SERIAL_DEF *pPortParam); int GM_CameraSerialTimer(SIO_PARAM_SERIAL_DEF *pPortParam); +int QueryPtzState(PTZ_STATE *ptz_state, int cmdidx, const char *serfile, unsigned int baud, int addr); + +int Query_BDGNSS_Data(BD_GNSS_DATA *BD_data, int samptime, const char *serfile, unsigned int baud); + +int GM_BdSerialTimer(SIO_PARAM_SERIAL_DEF *pPortParam); + +void GM_BdSerialComRecv(SIO_PARAM_SERIAL_DEF *pPortParam); + +void BdRecvData(SIO_PARAM_SERIAL_DEF *pPortParam, u_char *buf, int len); + +unsigned char BDXorCheck(unsigned char *msg, int len); + +void BD_NMEA0183_PortDataProcess(SIO_PARAM_SERIAL_DEF *curserial); + +char** BD_NMEA0183_SplitString(char *str, int *total_fields); + +int BD_get_BDRMC_data(SIO_PARAM_SERIAL_DEF *curserial); + #endif // __SENSOR_PROTOCOL_H__