#include #include #include #include "select_tool.h" #include "loc_tool.h" #include #include #include #include "config_file.h" #include "db_api/CDBConnPool.h" #include "websocket/wsTimerThread.h" #include "websocket/wsClientMgr.h" #include "timestamp.h" #include "monkey_car/monkeycar_area.h" #include "monkey_car/monkeycar_person.h" #include "special_area.h" #include "cardMgr.h" #include "ant.h" extern config_file config; //一张卡一个ct的所有不同天线的信息 struct one_ct_message_handle { static loc_tool_main m_loc_tool; ev::timer m_min_timer,m_max_timer; //loc_message. std::vector m_msg_list; card_location_base*m_card; const algo_config*m_ac=nullptr; int m_ct; bool m_min_timeout=false; ev::dynamic_loop * m_loop = nullptr; one_ct_message_handle(card_location_base*card) { m_card=card; m_ct=-1; } void reset() { m_ct=-1; m_min_timeout=false; m_msg_list.clear(); } void on_min_timer() { m_min_timer.stop(); if((int)m_msg_list.size()>=m_ac->best_msg_cnt) { m_max_timer.stop(); calc_location(); return; } m_min_timeout=true; } void on_max_timer() { m_max_timer.stop(); calc_location(); } void set(ev::dynamic_loop * loop) { m_loop = loop; m_min_timer.set(*m_loop); m_min_timer.set(this); m_max_timer.set(*m_loop); m_max_timer.set(this); } void on_message(ev::dynamic_loop *loop,const message_locinfo&loc) { if(m_loop == nullptr && loop!=nullptr) set(loop); else if(loop == nullptr) return; if(!m_msg_list.empty()&& m_ct!=loc.m_card_ct) { m_msg_list.clear(); } auto sitPtr = sit_list::instance()->get(loc.m_site_id); if(sitPtr==nullptr) { log_warn("分站信息缺失,SitId:%d",loc.m_site_id); return; } const site &s=*(sit_list::instance()->get(loc.m_site_id)); if(m_msg_list.empty()) { m_ct=loc.m_card_ct; m_ac=&s.config(); m_min_timeout=false; //这里构造loc_message 保存数据 m_msg_list.push_back(loc_message(s,loc.m_tof,loc.m_time_stamp,loc.m_card_id, loc.m_card_ct,loc.m_card_type,loc.m_ant_id,loc.m_rav,loc.m_acc, loc.m_sync_ct,loc.m_rssi)); //启动本CT的最小、最大两个定时器 m_min_timer.start(m_ac->min_wait_time); m_max_timer.start(m_ac->min_wait_time); return; } m_msg_list.push_back(loc_message(s,loc.m_tof,loc.m_time_stamp,loc.m_card_id, loc.m_card_ct,loc.m_card_type,loc.m_ant_id,loc.m_rav,loc.m_acc, loc.m_sync_ct,loc.m_rssi)); if(m_min_timeout && (int)m_msg_list.size()>=m_ac->best_msg_cnt) { calc_location(); m_max_timer.stop(); } } void calc_location() { auto v = m_msg_list; std::vector rc=std::move(m_loc_tool.calc_location(v)); if(!rc.empty()) m_card->on_location(std::move(rc),v); reset(); } }; struct card_message_handle { card_location_base*m_card; std::array m_ct_list; card_message_handle(card_location_base*card) { m_card=card; for(size_t i=0;i * loop,const message_locinfo&loc,bool is_history) { if(is_history) { log_warn("%s","当前代码没有处理历史消息记录。"); return; } // m_card->site_hover(loc.m_site_id); if(loc.m_batty_status == 2) { m_card->do_status(STA_TYPE::STATUS_LOW_POWER_); } else if(loc.m_callinfo == 0x80) { m_card->do_status(STA_TYPE::STATUS_HELP_); } m_ct_list[loc.m_card_ct&(m_ct_list.size()-1)]->on_message(loop,loc); } }; struct card_area { card_area() { m_site_area.reset(new site_area_hover); m_area_tool.reset(new area_tool); } std::shared_ptr m_site_area=nullptr; std::shared_ptr m_area_tool=nullptr; }; struct person:card_location_base,private card_area { std::weak_ptr m_monkeyPerson; person(std::string type,uint32_t cardid,uint16_t needdisplay,int16_t t,int32_t deptid) :card_location_base(type,cardid,needdisplay,t,deptid) { m_message_handle = new card_message_handle(this); } void on_message(zloop * loop,const message_locinfo&loc,bool is_history) { m_message_handle->on_message(loop,loc,is_history); } virtual void site_hover(int sid) { m_site_area->on_point(m_id,sid,0); } virtual void do_business(const point &pt) { //区域 m_area_tool->on_point(m_id,pt,m_speed,m_type); //考勤 m_site_area->on_point(m_id,0,this); // } //人卡升井后该线程要停掉 //手动升级需要补全区域得同时,需要进区域走区域业务 void set(ev::dynamic_loop * loop) { log_info("cardid_id %d",m_id); m_loop = loop; m_timer.set(*m_loop); m_timer.set(this); m_timer.start(1,1); } void reset(std::shared_ptr mp) { m_monkeyPerson = mp; } ~person(){} private: void on_timer() { YA::_CARD_POS_ cp; point pt = getSmoothPoint(); const auto lm = m_area_tool->getLandmark(); cp.enter_area_time = std::get<0>(lm); cp.rec_time = std::get<1>(lm); cp.map_id = std::get<2>(lm); cp.area_id = std::get<3>(lm); cp.landmark_id = std::get<4>(lm); cp.lm_direction = std::get<5>(lm); cp.landmark_dis=std::get<6>(lm); cp.biz_stat = state(); upt_card_pos(cp,pt); } int state() { int status = get_stat(); if(status == STATUS_NORMAL) { //超时 } return status; } point getSmoothPoint() { point pt; loc_point lp = m_smo_tool->smooth_strategy(); m_speed = lp.m_speed; m_stat = lp.m_stat; pt.x = lp.x; pt.y = -lp.y; if(auto p = m_monkeyPerson.lock() ) { if(p->is_on_bus()) { m_stat = 7; pt = p->getPoint(); } } return pt; } }; struct car:card_location_base,private card_area { int m_vehicle_category_id=0; car(std::string type,uint32_t cardid,uint16_t needdisplay,int16_t t,int32_t deptid,int32_t categoryid) :card_location_base(type,cardid,needdisplay,t,deptid) ,m_vehicle_category_id(categoryid) { m_message_handle=new card_message_handle(this); } virtual void site_hover(int sid) { m_site_area->on_point(m_id,sid,0); } virtual void do_business(const point &pt) { m_area_tool->on_point(m_id,pt,m_speed,m_type); m_site_area->on_point(m_id,0,this); } void set(ev::dynamic_loop * loop) { log_info("cardid_id %d",m_id); m_loop = loop; m_timer.set(*m_loop); m_timer.set(this); m_timer.start(1,1); } ~car(){} private: void on_timer() { make_package(); } int statbiz(int32_t special_id) { int status = get_stat(); if(status==STATUS_NORMAL) { //超速 //超时 //顺序不能变 } if(status == STATUS_LOST) { if(!m_area_tool->special_area()) { special_id = special_area_list::instance()->get_special_id(m_id,*this,m_vehicle_category_id); log_info("enter_special_area:%.2f,%2.f,id:%d,special_area_id:%d",x,y,m_id,special_id); if(special_id != -1) m_area_tool->change_area(m_id,m_speed,m_type,special_id);//自动拖车 } } return status; } void make_package() { int32_t special_id=-1; YA::_CARD_POS_ cp; point pt = getSmoothPoint(); const auto lm = m_area_tool->getLandmark(); cp.enter_area_time = std::get<0>(lm); cp.rec_time = std::get<1>(lm); cp.map_id = std::get<2>(lm); cp.area_id = std::get<3>(lm); cp.landmark_id = std::get<4>(lm); cp.lm_direction = std::get<5>(lm); cp.landmark_dis=std::get<6>(lm); int32_t biz_stat=statbiz(special_id); cp.biz_stat=biz_stat; //cp.down_time //cp.work_time; //cp.level_id; //for now cp.is_on_duty=1; upt_card_pos(cp,pt); if(biz_stat==STATUS_LOST && special_id != -1 && m_display==1) { cp.area_id = special_id; swsClientMgr.SendSpecialAreaProcess(cp); } } point getSmoothPoint() { loc_point lp = m_smo_tool->smooth_strategy(); m_speed = lp.m_speed; m_stat = lp.m_stat; lp.y = -lp.y; return lp; } }; loc_tool_main one_ct_message_handle::m_loc_tool; uint64_t card_list::getId(uint32_t cardid,uint64_t type) { return type<<32|cardid; } void card_list::init_vehicle() { std::unordered_map> map; std::string strategy = config.get("person.strategy","car1"); const char *sql = "SELECT ve.vehicle_id, ve.card_id, c.card_type_id, \ ve.dept_id, ve.group_id, v.vehicle_type_id, vt.vehicle_level_id, \ vt.is_railroad AS vt_is_railroad,ve.need_display ,ve.power_alarm,\ vt.vehicle_category_id,v.bigger_car_flag,vc.over_speed \ FROM dat_vehicle_extend ve \ LEFT JOIN dat_vehicle v ON ve.vehicle_id = v.vehicle_id \ LEFT JOIN dat_card c ON ve.card_id = c.card_id \ LEFT JOIN dat_dept d ON ve.dept_id = d.dept_id \ LEFT JOIN dat_group g ON ve.group_id = g.group_id \ LEFT JOIN dat_vehicle_type vt ON v.vehicle_type_id = vt.vehicle_type_id \ LEFT JOIN dat_vehicle_category vc ON vc.vehicle_category_id = vt.vehicle_category_id \ WHERE c.card_type_id = 2 AND c.state_id = 0;"; std::string Error; YADB::CDBResultSet DBRes; sDBConnPool.Query(sql,DBRes,Error); int nCount = DBRes.GetRecordCount( Error ); if (nCount > 0) { log_info( "init_staffer. The record count=%d\n", nCount ); while ( DBRes.GetNextRecod(Error) ) { unsigned int vehicle_id = 0; DBRes.GetField( "vehicle_id",vehicle_id, Error ); std::string card_id; DBRes.GetField( "card_id",card_id, Error ); uint32_t vsid = atoi(card_id.substr(3).c_str()); unsigned int card_type_id = 0; DBRes.GetField( "card_type_id",card_type_id, Error ); int dept_id = 0; DBRes.GetField( "dept_id",dept_id, Error ); int group_id = 0; DBRes.GetField( "group_id",group_id, Error ); int vehicle_type_id = 0; DBRes.GetField( "vehicle_type_id",vehicle_type_id, Error ); int vehicle_level_id = 0; DBRes.GetField( "vehicle_level_id",vehicle_level_id, Error ); int need_display = 0; DBRes.GetField( "need_display",need_display, Error ); int power_alarm = 0; DBRes.GetField( "power_alarm",power_alarm, Error ); int vehicle_category_id = 0; DBRes.GetField( "vehicle_category_id",vehicle_category_id, Error ); int bigger_car_flag= 0; DBRes.GetField( "bigger_car_flag",bigger_car_flag, Error ); double over_speed= 0; DBRes.GetField( "over_speed",over_speed, Error ); //for now vehicle_id = vsid; std::shared_ptr clb = std::make_shared(strategy,vehicle_id,need_display,card_type_id,dept_id,vehicle_category_id); uint64_t cardid = getId(vehicle_id,2); log_info("cardId:%llu,vehicle_id:%d dept_id:%d,need_display:%d---cardid:%s,categoryid:%d",cardid,vehicle_id,dept_id,need_display,card_id.c_str(),vehicle_category_id); map.insert({cardid,clb}); } } card_list::instance()->add(map); } void card_list::init_staffer() { std::unordered_map> map; std::string strategy = config.get("person.strategy","person1"); const char *sql = "SELECT staff_id, s.card_id, c.card_type_id, s.dept_id, s.group_id, s.occupation_id, \ ol.occupation_level_id,s.worktype_id,s.need_display \ FROM dat_staff_extend s \ LEFT JOIN dat_card c ON s.card_id = c.card_id \ LEFT JOIN dat_occupation o ON s.occupation_id = o.occupation_id \ LEFT JOIN dat_occupation_level ol ON ol.occupation_level_id = o.occupation_level_id \ WHERE c.card_type_id = 1 AND s.duty_id = 0 AND c.state_id = 0;"; std::string Error; YADB::CDBResultSet DBRes; sDBConnPool.Query(sql,DBRes,Error); int nCount = DBRes.GetRecordCount( Error ); if (nCount > 0) { log_info( "init_staffer. The record count=%d\n", nCount ); while ( DBRes.GetNextRecod(Error) ) { unsigned int staff_id = 0; DBRes.GetField( "staff_id",staff_id, Error ); std::string card_id; DBRes.GetField( "card_id",card_id, Error ); uint32_t vsid = atoi(card_id.substr(3).c_str()); unsigned int card_type_id = 0; DBRes.GetField( "card_type_id",card_type_id, Error ); int dept_id = 0; DBRes.GetField( "dept_id",dept_id, Error ); int group_id = 0; DBRes.GetField( "group_id",group_id, Error ); int occupation_id = 0; DBRes.GetField( "occupation_id",occupation_id, Error ); int occupation_level_id = 0; DBRes.GetField( "occupation_level_id",occupation_level_id, Error ); int need_display = 0; DBRes.GetField( "need_display",need_display, Error ); //for now; staff_id = vsid; std::shared_ptr clb = std::make_shared(strategy,staff_id,need_display,card_type_id,dept_id); uint64_t cardid = getId(staff_id,1); log_info("cardId:%llu,staff_id:%d dept_id:%d,need_display:%d--c-ard:%s",cardid,staff_id,dept_id,need_display,card_id.c_str()); map.insert({cardid,clb}); } } card_list::instance()->add(map); } void card_list::init_card_from_db() { init_staffer(); init_vehicle(); } void card_list::on_message(zloop *loop,const message_locinfo&loc,bool is_history) { //std::shared_ptrc=get(loc.m_card_id); uint64_t cardid = getId(loc.m_card_id,loc.m_card_type); const auto c=get(cardid); if(c==nullptr) { log_warn("数据库中未定义该卡的信息,card_id=%d", loc.m_card_id); return; } log_info("card message:site=%d,ant=%d,card=%d,tof=%lld,rav=%02X,acc=%02X,rssi=%d,stamp=%llu", loc.m_site_id,loc.m_ant_id,loc.m_card_id,loc.m_tof,loc.m_rav,loc.m_acc,loc.m_rssi,loc.m_time_stamp); c->on_message(loop,loc,is_history); } //-----------------card_location_base.. card_location_base::card_location_base(std::string type,uint32_t id,uint16_t dis,int16_t t,int32_t deptid) :card(id,dis,t,deptid) { select_tool_manage::instance()->create_tool(type,m_sel_tool,m_smo_tool); } void card_location_base::on_location(const std::vector&vp,const std::vector &lm ) { //ct timestamp; //m_ct = lm[0].m_card_ct; //m_time = lm[0].m_loc_time; loc_point pt = m_sel_tool->select_solution(vp,lm); pt.y=-pt.y; if(pt.m_useless) { x = pt.x; y = pt.y; Msg m; m.x=(int)x;m.y=(int)y;m.cmd=CMD_HANDLE;m.cardid=m_type<<32|m_id; cardMgr::instance()->tryPut(m); log_info("useful:card_id:%d,ct:%d,timestamp:%llu, loc_point,x:%.2f,y:%.2f ",m_id,m_ct,m_time,pt.x,pt.y); do_business(pt); } } void card_location_base::on_message(zloop * loop,const message_locinfo&loc,bool is_history) { if(m_loop == nullptr && loop != nullptr) set(loop); m_ct = loc.m_card_ct; m_time = loc.m_time_stamp; m_message_handle->on_message(loop,loc,is_history); } //前端推送位置函数 void card_location_base::upt_card_pos(YA::_CARD_POS_ &cp,const point &pt) { cp.x = pt.x; cp.y = pt.y; cp.z = pt.z; cp.Type=m_type; cp.ID = m_id; cp.speed = abs(ceil(m_speed)); cp.running_stat = m_stat; cp.dept_id = m_deptid; cp.display=m_display; cp.rec_time=m_time; swsTimerThrd.upt_card_pos(cp); } int card_location_base::get_stat() { //盲区>呼救>呼叫>超时>超速>正常 int status=STATUS_NORMAL; if(false) status = STATUS_CALL; if(false) status = STATUS_HELP; uint64_t now = time(0)*1000; status=(now-m_time>CARD_LOST_TIME_OUT)?STATUS_LOST:STATUS_NORMAL; return status; } card_location_base::~card_location_base() { } template<> std::shared_ptr single_base>::m_instance=std::make_shared();