#ifndef YASERVER_CLASSDEF_H_ #define YASERVER_CLASSDEF_H_ #define MAX_DIST_CACHE 4 //5 #define DIST_COUNT 4 #define ANCHOR_COUNT 4 #define KALMAN_OFFSET_COOR 0.01 #define KALMAN_OFFSET_MOVE 1 #define KALMAN_OFFSET_RANGING 0.01 #define KALMAN_INTERVAL 0.3 #define KALMAN_OFFSET_COOR_TRI 0.01 #define KALMAN_OFFSET_MOVE_TRI 1 #define KALMAN_OFFSET_RANGING_TRI 0.09 #define KALMAN_INTERVAL_TRI 1 #define ANTENNA_COUNT 2 #define ADHOC_COUNT 10 #define READER_TIMEOUT 20 #define OVER_TIME 480 * 60 //#define CARD_TYPE_ADHOC 3 #define MAX_SEMACOUNT 64 #define INVALID_COORDINATE -1 //算法类型 //#define ALGORITHM_TYPE_TOF #define ALGORITHM_TYPE_TDOA //#define ALGORITHM_TYPE_INS //使用惯导判断 //滤波功能开启 //#define FILTER_KALMAN #include #include #include #include #include #include #include #include //#include "winsock2.h" #include #include "Filter\KalmanFilter.h" #define MIN(x,y) (x < y ? x : y) #define MAX(x,y) (x > y ? x : y) using namespace std; //算法中使用的常量定义 const int MAX_CALC_POINTS = 30; const double INS_WEIGHT = 9.0; //惯导权重 const double UWB_WEIGHT = 1.0; //UWB权重 const double MAX_VECHILE_SPEED = 25.0; const double VECHILE_ACCELERATE_THRESHOLD = 5; const double PERSON_ACCELERATE_THRESHOLD = 3; enum TIMER_ID { TMR_SEND_COUNTING = 1, TMR_SEND_ALARM, TMR_SEND_DEVICE_STATE, TMR_SEND_POSTION, TMR_SYNC_READER_TIME, TMR_CLEAR_CALL_TIMER, TMR_SEND_CALL }; enum ALARM_FLAG{ AF_CARD_OVER_COUNT = 1, AF_CARD_OVER_TIME, AF_CARD_OVER_SPEED, AF_CARD_AREA_OVER_TIME, AF_CARD_AREA_OVER_COUNT, AF_CARD_AREA_FORBIDDEN,//1 这两个需要处理s AF_AREA_OVER_COUNT, AF_AREA_OVER_TIME, AF_AREA_FORBIDDEN //2 }; enum EDIT_TYPE_ID{ ET_INSERT = 0, ET_UPDATE, ET_DELETE }; enum ALARM_TYPE_ID { ATID_OVER_COUNT_PERSON = 1, ATID_OVER_TIME_PERSON, ATID_AREA_OVER_COUNT_PERSON, ATID_AREA_OVER_TIME_PERSON, ATID_AREA_LIMIT_PERSON, ATID_AREA_FORBIDDEN_PERSON, ATID_READER, ATID_OVER_SPEED, ATID_RUN_THE_RED_LIGHT, ATID_POWER, ATID_OVER_COUNT_VEHICLE, ATID_OVER_TIME_VEHICLE, ATID_AREA_OVER_COUNT_VEHICLE, ATID_AREA_OVER_TIME_VEHICLE, ATID_AREA_LIMIT_VEHICLE, ATID_AREA_FORBIDDEN_VEHICLE }; enum STATUS_DEVICE{ STATUS_DEVICE_NORMAL = 0, STATUS_DEVICE_ERROR, }; enum STATUS_CARD { STATUS_NORMAL = 0, //正常 STATUS_ERROR = 1, STATUS_ERROR_SERIOUS = 2, STATUS_POWER_LOWER = 1, //电量低 STATUS_POWER_LOWER_SERIOUS = 2, //电量极低 STATUS_OVER_TIME = 4, //超时 //STATUS_OVER_COUNT = 1, STATUS_OVER_SPEED = 8, //超速 STATUS_AREA_OVER_TIME = 16, //区域超时 //STATUS_AREA_OVER_COUNT = 1, STATUS_AREA_OVER_SPEED = 32, //区域超速 STATUS_AREA_FORBIDDEN = 64, //进入限制区域 STATUS_HELP = 128, //呼救 STATUS_HELP_DEALED = 256, // STATUS_CALL = 512, //呼叫 STATUS_LOST = 1024 //清除盲区 //STATUS_ERROR_DEALED, }; enum STORE_CARD_DATA_FLAG{ TEST_LOCATE_COMPARE = 0, TEST_LOCATE_DATA, HIS_LOCATION, HIS_RAW_DATA, HIS_AREA_LOCATION_ENTER, HIS_AREA_LOCATION_LEAVE, RPT_ATTEND_DOWN, RPT_ATTEND_UP, ALARM_CARD_OVER_TIME_START, ALARM_CARD_OVER_TIME_END, ALARM_CARD_OVER_SPEED_START, ALARM_CARD_OVER_SPEED_END, //ALARM_CARD_LOST_START, //ALARM_CARD_LOST_END, ALARM_CARD_LOW_POWER_START, ALARM_CARD_LOW_POWER_END, ALARM_CARD_OVER_TIME_AREA_START, ALARM_CARD_OVER_TIME_AREA_END, ALARM_CARD_OVER_SPEED_AREA_START, ALARM_CARD_OVER_SPEED_AREA_END, ALARM_CARD_AREA_FORBIDDEN_START, ALARM_CARD_AREA_FORBIDDEN_END, ALARM_CARD_HELP_START, ALARM_CARD_HELP_END }; enum STORE_AREA_DATA_FLAG{ ALARM_AREA_OVER_COUNT_PERSON_START = 0, ALARM_AREA_OVER_COUNT_PERSON_END, ALARM_AREA_OVER_COUNT_VEHICLE_START, ALARM_AREA_OVER_COUNT_VEHICLE_END, ALARM_AREA_FORBIDDEN_PERSON_START, ALARM_AREA_FORBIDDEN_PERSON_END, ALARM_AREA_FORBIDDEN_VEHICLE_START, ALARM_AREA_FORBIDDEN_VEHICLE_END, }; enum STORE_READER_DATA_FLAG{ ALARM_READER = 0, ALARM_READER_LOST_START, ALARM_READER_LOST_END }; enum STORE_MINE_DATA_FLAG{ ALARM_MINE_OVER_COUNT_PERSON_START = 0, ALARM_MINE_OVER_COUNT_PERSON_END, ALARM_MINE_OVER_COUNT_VEHICLE_START, ALARM_MINE_OVER_COUNT_VEHICLE_END }; enum LOCATE_TYPE { LT_COORDINATE = 0, LT_READER, LT_TDOA, }; enum FILTER_TYPE{ NO_FILTER = 0, FILTER_KALMAN = 1, }; struct SQLTHREAD_DATA//写数据库线程传递的参数 { char* pText;//数据库语句地址指针 int nRepeatTimes;//已经重试几次 }; // 定位坐标 struct _coordinate{ _coordinate(){ t = 0; reader_id = 0; tt = 0; d = 0.0; st = 0; x = 0.0; y = 0.0; z = 0.0; a = 0.0; v = 0.0; antenna_id = 0; d_offset = 0.0; special = 0; acceleration = 0; acce_state = 0; acce_state_last = 0; } int t; // 定位时间戳 int reader_id; unsigned long long tt; double d; // 距离 double x; // x坐标 double y; // y坐标 double z; // z坐标 double a; // 平面角度 double v; // 速度 int antenna_id; double d_offset; // 与显示距离的偏移,用来修正单基站的情况 int st; //同步序号 double acceleration; //加速度 int acce_state; //加速度状态 int acce_state_last; //加速度计上一次状态 int special; //分站是否属于特殊分站,0属于特殊分站,1普通分站 _coordinate& operator=(_coordinate &tmp){ t = tmp.t; reader_id = tmp.reader_id; tt = tmp.tt; d = tmp.d; st = tmp.st; x = tmp.x; y = tmp.y; z = tmp.z; a = tmp.a; v = tmp.v; antenna_id = tmp.antenna_id; d_offset = tmp.d_offset; special = tmp.special; acceleration = tmp.acceleration; acce_state = tmp.acce_state; acce_state_last = tmp.acce_state_last; return *this; } }; struct _point{ // 坐标 double x; double y; double z; }; struct sync_data{ double x; double y; double vx; double vy; int sync_num; //本次同步号 bool update; sync_data(){ x = 0.0; y = 0.0; vx = 0.0; vy = 0.0; sync_num = 0; update = false; } sync_data& operator=(sync_data&tmp){ x = tmp.x; y = tmp.y; vx = tmp.vx; vy = tmp.vy; sync_num = tmp.sync_num; update = tmp.update; return *this; } }; struct _call_info_card { int card_id; int card_type; int call_type; string str_card_id; time_t start_time; int time_out; bool is_success; }; typedef map CallInfoCardMap; struct _call_info_reader { bool is_call_all; bool is_start_call; //true,开始呼叫;false,取消呼叫 BYTE call_type; int cards_count; CallInfoCardMap mpCard; }; typedef map CallInfoReaderMap; // 分站接收时间定义 struct ReceiveData{ unsigned int reader_id; // 分站号 unsigned short antenna_id; // 天线号 long long rec_time_stamp; // 分站接收时间,一个5字节的无符号数 int special; double x; //分站的x坐标 double y; //分站的y坐标 double z; //分站的z坐标 ReceiveData(){ reader_id = -1; antenna_id = -1; rec_time_stamp = 0; x = y = z = 0.0; special = -1; }; }; typedef unordered_map ReceiveDataMap; //typedef unordered_map ReceiveDataMap; struct INFO_PRE{ int t; long long detaT; double dist; int ant; int sta_num; }; struct POS{ double posx; double posy; double posz; double pos_radius; //保存定位结果的两个分站信息 int nFirstReader; int nSecondReader; //精度参考 double dFirstDiff; double dSecondDiff; POS(){ nFirstReader = INVALID_COORDINATE; nSecondReader = INVALID_COORDINATE; posx = 0; posy = 0; posz = 0; dFirstDiff = 0; dSecondDiff = 0; pos_radius = 0; } POS& operator=(POS& tmp){ nFirstReader = tmp.nFirstReader; nSecondReader = tmp.nSecondReader; posx = tmp.posx; posy = tmp.posy; posz = tmp.posz; dFirstDiff = tmp.dFirstDiff; dSecondDiff = tmp.dSecondDiff; pos_radius = tmp.pos_radius; return *this; } }; struct RESULT{ double x[3]; double y[3]; double z[3]; int nCount; }; class Mine; class Area; class Reader; class Card; class MapInfo; class Dept; class ReaderPath; typedef map CardMap; typedef map AreaMap; typedef map ReaderMap; typedef map MapInfoMap; typedef map DeptMap; typedef map AlarmTypeMap; typedef map ReaderPathMap; typedef unordered_map TDOAReaderPathMap; typedef unordered_map DistMap; struct DistQueMapItem { WORD cardstamp; DistMap distmap; }; typedef deque DistQueMap; // 地图 class MapInfo{ public: MapInfo(void); ~MapInfo(void); public: int map_id; string map_path; string map_name; double map_width; double map_height; double map_scale; int map_type; AreaMap map_area_list; ReaderMap map_reader_list; CardMap map_card_list_person; CardMap map_card_list_vehicle; }; // 区域 class Area // 矩形 { private: std::vector split(std::string str,std::string pattern); double get_vertex(std::string src); // 顶点 public: Area(void); ~Area(void); void init_border(string sz_path); bool is_in_polygon(_point p); public: int map_id; int area_id; string area_name; string area_type_name; int area_type_id; string path; // 多边形 // 人员 int over_count_person; int over_time_person; int under_count_person; int under_time_person; // 车辆 int over_count_vehicle; int over_time_vehicle; int under_count_vehicle; int under_time_vehicle; int polygon_count; _point* polygon; // 坐标 //double x; //double y; //double z; //double sr; // 短半径 //double lr; // 长半径 //double x1, y1, z1; // 矩形四个顶点 //double x2, y2, z2; //double x3, y3, z3; //double x4, y4, z4; double rect_left; double rect_right; double rect_top; double rect_bottom; // 区域人数 int count_person; int count_vehicle; int count_card; // 是否写考勤 int is_att; // 0 停车场外,1 停车场内 // bool is_area_over_time_person; // 车辆超时 bool is_area_over_time_vehicle; // 人员超时 int count_area_over_time_person; // 超时人数 int count_area_over_time_vehicle; // 超时车数 time_t time_over_time_person; // 开始超时时间 time_t time_over_time_vehicle; // 开始超时时间 bool is_area_over_count_person; // 人员超员 bool is_area_over_count_vehicle; // 车辆超员 int count_area_over_count_person; int count_area_over_count_vehicle; time_t time_over_count_person; // 开始时间 time_t time_over_count_vehicle; // 开始时间 bool is_area_forbidden_person; bool is_area_forbidden_vehicle; int count_area_forbidden_person; int count_area_forbidden_vehicle; time_t time_forbidden_person; // 开始时间 time_t time_forbidden_vehicle; // 开始时间 CardMap area_card_list_person; CardMap area_card_list_vehicle; }; // 自组网预置坐标 class Adhoc { public: Adhoc(); ~Adhoc(); public: int adhoc_id; double x; double y; double z; int idx; }; // 天线 class Antenna { public: Antenna(void); ~Antenna(void); public: int antenna_id; double antenna_x; double antenna_y; double antenna_z; double antenna_angle; }; // 分站 class Reader { public: Reader(void); ~Reader(void); public: int reader_id; // 分站号 string reader_name; // 分站名称 int device_type_id; int pos_state; // 位置状态 1井上,2井下 string ip; double reader_x; double reader_y; double reader_z; double reader_angle; double reader_interval_time; int map_id; // 所在地图 int area_id; // 所属区域 double map_scale; // 比例尺 //double rec_time; // 接收数据时间 time_t rec_time; time_t reader_time; // 分站时间 time_t lost_time; int temperature; // 温度 int tick_count; // 计数器 int state; // 状态 0 正常, 1 故障 int sync_level; int state_old; // 上一次状态 Antenna* ant[ANTENNA_COUNT]; // 两个天线 Adhoc* adhoc[ADHOC_COUNT];// 自组网节点预置坐标 map readerCoveragePath; bool bIsInitCoverage; int m_nIsSpecial; public: string get_state_text(); }; // 卡 class Card { public: Card(void); ~Card(void); Card(string cardid, int cardtype,double z_offset, double offset_x = 12.0, double offset_y =12.0); public: CRITICAL_SECTION m_csCard; public: int card_type; // 卡类型 0x01人, 0x02车 //int64_t card_id; // 卡唯一标识, 高位为卡号,低位为卡类型, ((card_id << 8) | card_type) string card_id; // 人员 string level; // 级别 string occupation; // 职务 // 人员、车辆 string id; // 编号,人员或车辆 string name; // 姓名、车辆名称 string number; // 身份证号码,车牌号码 string photo; // 照片 string company; // 单位 string department; // 部门 int dept_id; int group_id; string group; // 班组 string worktype; // 工种、车辆类型 //time_t deal_time; // 最后处理卡逻辑时间 SYSTEMTIME deal_time; time_t rec_time; // 最后接收时间 time_t down_time; // 入井时间 time_t up_time; // 升井时间 time_t enter_area_time; // 进入区域时间 time_t enter_reader_time; // 进入分站时间 time_t low_power_time; // 电量低开始时间 //time_t enter_park_time; // 回场时间 //time_t leave_park_time; // 出场时间, 开始工作时间 double coor_offset_x; double coor_offset_y; double x; double y; double z; double a; // 上次定位时的角度 int t; // 上次定位时的时间戳 double z_offset; bool init_postion; bool is_first_location; double v; //速度 double m_dAverageV; //平均速度 double xx; double yy; double zz; double x1, x2, x3, x4; double y1, y2, y3, y4; double z1, z2, z3, z4; double last_x; double last_y; double last_z; double stored_x; double stored_y; double stored_z; double last_vx; double last_vy; int state; // 0 正常, 共32bit,每个bit代表一个状态,从右起: // 第一位 0x01 井下超时, 第二位 0x02 区域超时, 第三位 0x04 超速, 第四位 0x08, 进入限制区域 // 状态,故障、电量低等 int state_moving; // 运动状态, 0 静止,1 启动 int state_biz; //业务状态,呼叫/超时/进入禁区等 // 电量低、 呼叫、呼救 int status_over_time; // 0 未超时,1 超时 int status_over_speed; // 0 未超速,1 超速 int status_area_over_time; // 0 未区域超时, 1 区域超时 int status_area_over_speed; // 0 未区域超速, 1 区域超速 int status_area_forbidden; // 0 未进入限制区域, 1 进入限制区域 int status_help; // 0 未呼救, 1 呼救, 2 已处理呼救 int status_call; // 0 未呼叫 1 呼叫 int status_power; // 0 电量正常,1 电量低 int status_lost; // 0 未进入盲区,1 盲区状态 int map_id; // 当前地图 double map_scale; // 地图比例尺 int map_id_old; // 上次测距所在地图 int area_id; // 当前区域 int reader_id; // 当前分站 Reader* p_reader; ReaderPathMap* pReaderPathMap; TDOAReaderPathMap* pTdoaReaderPathMap; _coordinate** p_dists; _coordinate** p_dists_locate; _coordinate last_locate; _coordinate origin_locate; double m_dFirstDiff; double m_dSecondDiff; DistQueMap _dists; int time_stamp_max; // 最大时间戳,即需要计算定位的时间戳 int time_stamp_cal; //int get_pos_state() const { return pos_state; } //void set_pos_state(int val) ; //int get_pos_state_count() const { return pos_state_count; } int pos_state; // 位置状态,0初始化,1井下,2井上,3车场分站 int pos_state_old; //int pos_state_last; int pos_state_count; // 当前位置状态确认次数 int pos_state_park; // 在停车场区域状态 int pos_state_park_old; //int pos_state_park_last; int pos_state_park_count; int m_nFilterType; int m_nLastLocateT; int m_nCalcSyncNum; //卡在算法中的同步号,此同步号和卡的实时同步号并不一定一致 int m_nSyncNumInList; //从队列中取出的大于5的同步号 //int last_area_type_id; //int cur_area_type_id; bool issent; // true 已发送至客户端,false 新数据,需要发送至客户端 bool issaved; //true 已保存到数据库,false 生成新的考勤记录,需要保存到数据库 bool isdealed; // 已经处理 bool isreceive; // 接收到 bool is_pos_changed; bool is_deal_by_algo; bool is_hist; bool is_need_cal; bool m_bUseFilter; bool is_mine_over_time; // 是否井下超时 bool is_area_over_time; // 是否区域超时, 区域超时分车辆超时、人员超时 time_t time_area_over_time; // 区域超时开始时间 time_t time_over_time; // 井下超时开始时间 time_t time_area_forbidden; // 进入限制区域时间 time_t time_over_speed; // 超速开始时间 time_t time_low_power; void set_reader(Reader* preader); bool is_pos_state_changed(int nval); // 入\升井状态变化 bool is_pos_state_pack_changed(int nval); void add_dist(_coordinate* dist); void remove_dist_head(); string concat(int reader_id, int ant_id); time_t get_working_time(); string get_state_text(); string get_acc_text(); double get_speed(); int get_effictive_dist_count(int offset = 0); void set_reader_path(ReaderPathMap *rpm); void set_reader_path(TDOAReaderPathMap* trpm); void inspect_coordinate(int acce_state,int acce_state_last); void algo_tof(int cnt); void algo_tdoa(int cnt); public: // 滤波算法相关 //CalLocation* cal_location; CalLocation3* cal_location3; //Point2* p2_anchors; Point3* p3_anchors; //bool is_init_kalman; CKalmanFilter* m_pKalmanFilter; //int m_max_stamp; // 最大的时间戳,即最近采集的数据 list m_syncNumList; int last_s_locate_reader[2]; //上一次定位成功的分站信息 double ins_weight; double uwb_weight; double weight; int acc_change_state; //加速度计状态改变,0为未改变,1为改变 int acce_cur_state; //在算法中保存当前加速度状态,保存这两个值的原因是在多线程情况下accelerate_state和accelerate_state_last状态可能变化 int acce_last_state; //在算法中保存上一次加速度状态 bool is_anchor_changed; void get_coordinate(); void get_coordinate(int cnt); void get_coordinate_3d(int cnt); void get_coordinate_2d(int cnt); void set_anchors(int cnt); void EnableFilter(int nType); int FindDistMap(int cardstamp); private: bool b_long_interval; //上一次定位的间隔时间差大于10s public: // 采集到的底层数据 int reader_tickcount; int time_stamp; // 定位时间戳 int ranging_type; // 报文类型 tof,tdoa int accelerate_state; // 加速度 int antenna_id; // 天线号 double antenna_angle; // 天线角度 double distance; // 距离 int64_t flying_time; // 飞行时间 int power_state; // 电量 int sync_num; int time_stamp_last; // 定位时间戳 int context_type_last; // 报文类型 tof,tdoa int accelerate_state_last; // 加速度 int antenna_id_last; // 天线号 double antenna_angle_last; // 天线角度 double distance_last; // 距离 int64_t flying_time_last; // 飞行时间 int power_state_last; // 电量 int reader_id_last; //上一次定位时间戳的分站id string str_his_time; string str_rec_time; }; class Dept { public: Dept(); ~Dept(); Dept(int id, string name); private: public: int dept_id; string dept_name; CardMap dept_card_list_person; CardMap dept_card_list_vehicle; }; /* * 地图集路径描述 */ class ReaderPath{ public: ReaderPath(){ bIsInit = false; nRealCalcPoints = 0; x[0] = x[1] = y[0] = y[1] = 0; for(int i=0;i