Forráskód Böngészése

fix websocket bug

zhuyf 3 éve
szülő
commit
06ea2751a6

+ 49 - 26
ant.cpp

@@ -7,7 +7,6 @@
 #include "tool_time.h"
 #include "area.h"
 #include "card_path.h"
-//template<> std::shared_ptr<sit_list> single_base<sit_list, int, std::shared_ptr<site>>::m_instance=std::make_shared<sit_list>();
 
 int site::index()const
 {
@@ -31,10 +30,10 @@ const algo_config&site::config()const
 	return g_config[index()];
 }
 
-void ant::set_path(const std::vector<line_v>&v_line,std::vector<line_v>::const_iterator itm)
+void ant::set_path(const std::vector<line_v>& v_line, std::vector<line_v>::const_iterator itm)
 {
-	auto it=itm;
-	for(int i=0;i<2 && it!=v_line.end();++it,++i)
+	auto it = itm;
+	for(int i = 0; i < 2 && it != v_line.end(); ++it,++i)
 		m_path[0][i]=*it;
 
 	it=itm-1;
@@ -61,15 +60,15 @@ void ant::set_path(const std::vector<line_v>&v_line_)
 	std::vector<line_v> vl(v_line_);
 	vl.reserve(vl.size()+2);
 	//找到距离天线最近的端点
-	auto min_it=vl.begin();
-	double dist=10;
-	for(auto it=vl.begin();it!=vl.end();it++)
+	auto min_it = vl.begin();
+	double dist = 10;
+	for(auto it = vl.begin(); it != vl.end(); it++)
 	{
-		double d=it->as_line().dist(*this);
-		if(d<dist)
+		double d = it->as_line().dist(*this);
+		if(d < dist)
 		{
-			dist=d;
-			min_it=it;
+			dist = d;
+			min_it = it;
 		}
 	}
 
@@ -79,13 +78,13 @@ void ant::set_path(const std::vector<line_v>&v_line_)
 		return;
 	}
 
-	if(abs(min_it->v[0].dist(*this)-dist)<1)
+	if(abs(min_it->v[0].dist(*this) - dist) < 1)
 	{
-		set_path(vl,min_it);
+		set_path(vl, min_it);
 	}
-	else if(abs(min_it->v[1].dist(*this)-dist)<1)
+	else if(abs(min_it->v[1].dist(*this) - dist) < 1)
 	{
-		set_path(vl,min_it+1);
+		set_path(vl, min_it+1);
 	}
 	else
 	{
@@ -166,11 +165,11 @@ void site::set_path(const std::vector<line_v>&v_line)
 		log_info("path-id=%d,line=%s",i,target[i].to_string().c_str());
 	}
 
-	for(int i=0,c=m_ant.size();i<c;i++)
+	for(int i = 0,c = m_ant.size(); i < c; i++)
 	{
 		if(m_ant[i].empty())
 		{
-			log_error("分站未设置天线坐标 site_id=%d,ant_index=%d",m_id,i);
+			log_error("分站未设置天线坐标 site_id=%d,ant_index=%d", m_id, i);
 			continue;
 		}
 		m_ant[i].set_path(target);
@@ -178,6 +177,17 @@ void site::set_path(const std::vector<line_v>&v_line)
 	m_path_empty= !m_ant[0][0].valid() && !m_ant[0][1].valid() ;
 }
 
+double site::get_site_dist(const int& sid)
+{
+    auto it_site = sit_list::instance()->get(sid);
+
+    if(it_site){
+        return this->dist(*it_site);
+    }else{
+        return 0.0;
+    }
+}
+
 std::vector<point> ant::getsol(const double &dist) const
 {
 	std::vector<point> v;
@@ -189,7 +199,7 @@ std::vector<point> ant::getsol(const double &dist) const
 		point pt;
 		double d  = dist;
 
-        logn_info(3, "[pdoa] dist=%.2f, line.length()=%.2f, %s", dist, p.m_line[0].length(), p.to_str().c_str());
+        //logn_info(3, "[pdoa] dist=%.2f, line.length()=%.2f, %s", dist, p.m_line[0].length(), p.to_str().c_str());
 		if(dist <= p.m_line[0].length())
 		{
 			d += d*p.m_line[0][0].z;
@@ -258,9 +268,12 @@ void sit_list::read_ant_path(int id)
 		auto site_ptr=sit_list::instance()->get(reader_id);
 		if(nullptr==site_ptr)
 		{
-			log_error("定义了分站路径,但是没有定义分站:%d",reader_id);
+			log_error("[site] 定义了分站路径,但是没有定义分站:%d",reader_id);
 			continue;
-		}
+		}else if(site_ptr->m_num_dims != 1){
+            log_info("[site] 多维定位分站,无需定义路径:%d", reader_id);
+            continue;
+        }
 
 		int pid=0;
 		DBRes.GetField( "tof_flag",pid, Error );
@@ -363,9 +376,12 @@ void sit_list::read_ant_path(int id)
 		auto sit_ptr=sit_list::instance()->get(vl.first);
 		if(!sit_ptr)
 		{
-			log_error("定义了分站路径,但是没有定义分站:%d",vl.first);
+			log_error("[site] 定义了分站路径,但是没有定义分站:%d",vl.first);
 			continue;
-		}
+		}else if(sit_ptr->m_num_dims > 1){
+            log_info("[site] 多维定位分站,无需定义路径:%d", vl.first);
+            continue;
+        }
 
 		sit_ptr->set_path(vl.second);
         point p;
@@ -386,7 +402,7 @@ void sit_list::init_site(const std::string &ids /*=""*/)
 {
      std::string sql = "SELECT reader_id, reader_type_id, dat_reader.map_id, \
              area_id, device_type_id, dimension, dat_map.scale,need_power_alarm\
-			 ,x,y, pdoa_offset, pdoa_direction\
+			 ,x,y, pdoa_offset, pdoa_direction, isSpecial\
              FROM dat_reader, dat_map where \
              dat_reader.map_id=dat_map.map_id and state=0";
 
@@ -459,8 +475,10 @@ void sit_list::init_site(const std::string &ids /*=""*/)
          site_ptr->create_area();
 
          double x = 0, y = 0;
-         DBRes.GetField( "x",x, Error );
-         DBRes.GetField( "y",y, Error );
+         DBRes.GetField("x", x, Error);
+         DBRes.GetField("y", y, Error);
+         site_ptr->x = x;
+         site_ptr->y = y;
 
          double offset = 0.0;
          DBRes.GetField("pdoa_offset", offset, Error);
@@ -471,7 +489,12 @@ void sit_list::init_site(const std::string &ids /*=""*/)
             site_ptr->m_pdoa_direction = direction;
          }
 
-		 log_info ("site_position: site=%d, x=%.2lf, y=%.2lf, area_id=%d, m_scale=%.2f, pdoa_offset=%.2f, pdoa_direction=%d", reader_id, x, y, area_id, scale, offset, direction);
+         int special = 0;
+         if(DBRes.GetField("isSpecial", special, Error)){
+            site_ptr->m_special = special;
+         }
+
+		 log_info ("site_position: site=%d, x=%.2lf, y=%.2lf, area_id=%d, m_scale=%.2f, pdoa_offset=%.2f, pdoa_direction=%d, special=%d", reader_id, x, y, area_id, scale, offset, direction, special);
      }
 }
 

+ 4 - 1
ant.h

@@ -93,7 +93,7 @@ struct site:point,std::enable_shared_from_this<site>
 {
     static algo_config g_config[];
     int      m_algo;			// TOF:0, TDOA:1, PDOA:2
-    int      m_num_dims;	    // 1维:0, 2维:1, 3维:2
+    int      m_num_dims;	    // 1维:1, 2维:2, 3维:3
     double  m_scale = 2.0;  // 地图比例尺
     point    m_position;
     mutable double m_height=1.5;
@@ -130,6 +130,7 @@ struct site:point,std::enable_shared_from_this<site>
 
 	std::array<int,32>	m_timeoff_count;
 	int  m_package_count=0;
+    int  m_special = 0;
 
     site(int id=-1);
 
@@ -321,6 +322,8 @@ struct site:point,std::enable_shared_from_this<site>
     {
         m_algo = _algo;
     }
+
+    double get_site_dist(const int& sid);
 };
 
 struct visit_site_status:visitor<std::shared_ptr<site>>

+ 1 - 1
card.cpp

@@ -41,7 +41,7 @@ void card_list::init_staffer(const std::string & lszId64)
 	
 	if(map.empty())
 	{
-		log_error("增加或修改失败,数据库中找不到: card_id=%", lszId64.c_str());
+		log_error("增加或修改失败,数据库中找不到: card_id=%s", lszId64.c_str());
 		return ;
 	}
 

+ 13 - 10
card_base.cpp

@@ -238,7 +238,7 @@ void card_location_base::upt_card_pos(YA::_CARD_POS_&cp, point &pt)
     else
          _p = pt;
 	
-    cp.Type     =   m_type;
+    cp.Type     = m_type;
 	cp.ID       = m_id;
 	cp.speed    = abs(ceil(m_speed));
 	cp.x        = tool_other::round(_p.x,3);
@@ -312,6 +312,8 @@ void  card_location_base::clear()
     m_last_ct = 0;
     m_last_dist = 0.0;
     m_pdoa_diff = m_last_pdoa_diff = 100.0;
+    m_last_over_site = false;
+    m_cache_nums = 0;
     m_cb_pdoa.clear();
     m_cb_tof.clear();
     m_cb_point.clear();
@@ -348,20 +350,21 @@ void card_location_base::put_traffic_light(card_pos& cp)
     }
     light_message lm;
 
-    lm.m_cmd = cmd_card_data;
-    lm.m_pos.x = cp.x;
-    lm.m_pos.y = cp.y;
-    lm.m_pos.z = cp.z;
-    lm.m_pos.m_card_id = m_id;
-    lm.m_pos.m_type = m_type;
-    auto site_ptr = get_area_tool()->m_site;
-    if(site_ptr){
+    lm.m_cmd            = cmd_card_data;
+    lm.m_pos.x          = cp.x;
+    lm.m_pos.y          = cp.y;
+    lm.m_pos.z          = cp.z;
+    lm.m_pos.m_card_id  = m_id;
+    lm.m_pos.m_type     = m_type;
+    lm.m_pos.m_site_id  = cp.reader_id;
+    auto site_ptr       = get_area_tool()->m_site;
+    if(site_ptr){   
         lm.m_pos.m_area_id = site_ptr->m_area_id;
     }
     //lm.m_pos.m_bigger = 0;
     lm.m_pos.m_speed = m_speed;
 
-    log_info("[traffic_light] put locate info into traffic light module, card_id=%d, ctype=%d, x=%.2f, y=%.2f", m_id, m_type, x, y);
+    log_info("[traffic_light] put locate info into traffic light module, card_id=%d, ctype=%d, x=%.2f, y=%.2f, site_id=%d", m_id, m_type, x, y, cp.reader_id);
     traffic_light_manager::instance()->put(lm);
 }
 

+ 2 - 0
card_base.h

@@ -99,6 +99,8 @@ struct card_location_base:card,std::enable_shared_from_this<card_location_base>
     uint16_t m_last_site_id = 0;                // 卡上一次定位的分站id
     uint64_t m_last_recv_time = 0;              // 卡上一次接收时间
     int m_last_site_dir = -1;                   // 卡上一次定位的分站天线1朝向
+    bool m_last_over_site = false;              // 卡是否过分站
+    int m_cache_nums = 0;                       // 过分站后缓存的数据个数
     int m_buff_size = 0;
     float m_pdoa_diff = 100.0;                  // pdoa分站当前上传相位差
     float m_last_pdoa_diff = 100.0;             // pdoa 分站上一帧数据的相位差

+ 10 - 5
card_car.cpp

@@ -43,7 +43,7 @@ void car::do_business(const std::shared_ptr<site>&site,const point &pt,double ac
 	m_area_tool->on_point(shared_from_this(),pt);
 	m_timeval = m_time;
 	handle_three_rates(pt);
-    handle_traffic_light(pt);
+    handle_traffic_light(pt, site->m_id);
     if(m_enable_anti_collision){
         handle_anti_coll(pt, site->m_id);
     }
@@ -156,7 +156,7 @@ void car::handle_three_rates(const point &pt)
 	put_three_rates(cp);
 }
 
-void car::handle_traffic_light(const point& p)
+void car::handle_traffic_light(const point& p, const int& sid)
 {
     card_pos cp;
     cp.x = p.x;
@@ -164,7 +164,8 @@ void car::handle_traffic_light(const point& p)
     cp.z = p.z;
     cp.biz_stat = get_stat();
     cp.map_id = m_area_tool->get_mapid();
-    cp.vibration = m_acc; 
+    cp.vibration = m_acc;
+    cp.reader_id = sid;
     put_traffic_light(cp);
 }
 
@@ -194,10 +195,14 @@ void car::make_package()
 	cp.map_id    = m_area_tool->get_mapid();
 
 	cp.biz_stat  = get_stat();
-	cp.down_time = m_mine_tool->get_down_time();
+	//cp.down_time = m_mine_tool->get_down_time();
 	cp.work_time = m_mine_tool->get_work_time();
 	cp.is_on_duty= m_mine_tool->is_on_duty();
-	upt_card_pos(cp, pt);
+    
+    cp.down_time = m_last_point.x;
+    cp.z         = m_last_point.y;
+	
+    upt_card_pos(cp, pt);
 
     uint64_t _now = tool_time::now_to_ms();
     pt.m_time = _now;

+ 1 - 1
card_car.h

@@ -41,7 +41,7 @@ public:
 	virtual void get_card(bool);
 private:
 	void handle_three_rates(const point &pt);
-    void handle_traffic_light(const point& pt);
+    void handle_traffic_light(const point& pt, const int& sid);
     void handle_anti_coll(const point& pt, const int& sid);
 	void on_timer();
 	void make_package();

+ 6 - 2
common.h

@@ -4,6 +4,7 @@
 #define LENGTH_SQL 2000
 #define SPEED_COUNT_LIMIT 5
 #define READER_TIMEOUT 20
+#define LIGHT_TIMEOUT  30
 #define PI 3.1415926
 #define TPI (2*3.1415926)
 #define CARD_LOST_TIME_OUT (60*1000)
@@ -106,7 +107,9 @@ enum OBJECT_TYPE
     ///标识卡,包括人员、车辆、自组网等
     OT_CARD = 9,
     //一人多卡
-    OT_MORE_CARD=11
+    OT_MORE_CARD=11,
+    // 红绿灯
+    OT_DEVICE_LIGHT=15
 };
 
 enum EVENT_DIS_TYPE
@@ -122,7 +125,8 @@ enum EVENT_TYPE{
     ET_OVER_COUNT_VEHICLE = 2,              // 井下车辆超员
     ET_AREA_OVER_COUNT_PERSON = 3,	        // 区域人员超员
     ET_AREA_OVER_COUNT_VEHICLE = 4,	        // 区域车辆超员
-    ET_READER_ERROR = 6,                    //
+    ET_READER_ERROR = 6,                    // 分站通信异常
+    ET_LIGHT_ERROR = 8,                     // 红绿灯通信异常
 
     ET_CARD_LOW_POWER_SERIOUS = 12,         // 电量极低
     ET_CARD_OVER_TIME_PERSON = 13,          // 人员井下超时

+ 2 - 2
db/db_card.cpp

@@ -118,8 +118,8 @@ namespace db_card
 	        
             map.insert({cardid,clb});
 
-            log_info("cardId:%llu,id:%d dept_id:%d,need_display:%d-cardid:%s,categoryid:%d,vchile_id:%d,type:%d,vehicle_type_id:%d, anti_collision:%d",
-                    cardid,
+            log_info("cardId:%s,id:%d dept_id:%d,need_display:%d-cardid:%s,categoryid:%d,vchile_id:%d,type:%d,vehicle_type_id:%d, anti_collision:%d",
+                    card_id.c_str(),
                     vsid,
                     dept_id,
                     need_display,

+ 0 - 2
db/db_card.h

@@ -1,4 +1,3 @@
-
 #ifndef _db_card_h_
 #define _db_card_h_
 
@@ -10,7 +9,6 @@ namespace db_card
 	//const std::string & lszId64 = 0010000001102
 	std::unordered_map<uint64_t,std::shared_ptr<card_location_base>> load_person(const std::string & lszId64,const std::string&);
 	std::unordered_map<uint64_t,std::shared_ptr<card_location_base>> load_car(const std::string & lszId64);
-
 }
 
 #endif

+ 41 - 6
event.cpp

@@ -1,17 +1,16 @@
 #include "event.h"
-
 #include<string>
-
 #include "ant.h"
 #include "area.h"
 #include "card.h"
 #include "common_tool.h"
 #include "websocket/constdef.h"
 #include "db/db_api/CDBSingletonDefine.h"
-#include"tool_time.h"
-#include"ant.h"
-#include"db/db_tool.h"
+#include "tool_time.h"
+#include "ant.h"
+#include "db/db_tool.h"
 #include "mine.h"
+#include "module_service/module_traffic_light_manager.h"
 
 uint64_t ya_event::get_list_id()
 {
@@ -44,6 +43,7 @@ struct area_event:Event
     {}
     virtual std::shared_ptr<ya_event> on_message(EVENT_TYPE et,uint64_t id,bool f);
 };
+
 struct device_reader_event:Event
 {
     device_reader_event()
@@ -51,6 +51,7 @@ struct device_reader_event:Event
     {}
     virtual std::shared_ptr<ya_event> on_message(EVENT_TYPE et,uint64_t id,bool f);
 };
+
 struct card_event:Event
 {
     card_event()
@@ -59,6 +60,14 @@ struct card_event:Event
     virtual std::shared_ptr<ya_event> on_message(EVENT_TYPE et,uint64_t id,bool f);
 };
 
+struct light_event:Event{
+    light_event()
+        : Event(OT_DEVICE_LIGHT)
+    {}
+
+    virtual std::shared_ptr<ya_event> on_message(EVENT_TYPE et, uint64_t id, bool f);
+};
+
 static event_tool et;
 event_tool * event_tool::instance()
 {
@@ -70,6 +79,7 @@ void event_tool::make_event_object()
     m_map[OT_AREA] = std::make_shared<area_event>();
     m_map[OT_DEVICE_READER] = std::make_shared<device_reader_event>();
     m_map[OT_CARD] = std::make_shared<card_event>();
+    m_map[OT_DEVICE_LIGHT] = std::make_shared<light_event>();
 }
 
 void event_tool::handle_event(OBJECT_TYPE ot,EVENT_TYPE et,uint64_t id,double limit_value,double cur_value,bool f,EVENT_DIS_TYPE edt/*=DT_COMMON*/,const std::string &desc/*=""*/)
@@ -145,7 +155,6 @@ void Event::handle_alarm_event(EVENT_TYPE et,uint64_t id,double limit_value,doub
     }
 }
 
-
 std::shared_ptr<ya_event> mine_event::on_message(EVENT_TYPE et,uint64_t id,bool f)
 {
     std::shared_ptr<ya_event> event_ptr=nullptr;
@@ -195,6 +204,10 @@ std::shared_ptr<ya_event> device_reader_event::on_message(EVENT_TYPE et,uint64_t
             log_info("create_event.can not find site :%d",id);
             return event_ptr;
         }
+        if(site_ptr->m_special){
+            //log_info()
+            return event_ptr;
+        }
         event_ptr=create_event(std::to_string(id),et);
         event_ptr->m_area_id =  site_ptr->m_area_id;
         event_ptr->m_map_id = site_ptr->m_map_id;
@@ -238,6 +251,28 @@ std::shared_ptr<ya_event> card_event::on_message(EVENT_TYPE et,uint64_t id,bool
     return event_ptr;
 }
 
+std::shared_ptr<ya_event> light_event::on_message(EVENT_TYPE et, uint64_t id, bool f)
+{
+    std::shared_ptr<ya_event> event_ptr = nullptr;
+
+    if(f){
+        auto light_ptr = traffic_light_manager::instance()->get(id);
+        if(!light_ptr)
+        {
+            log_info("create_event.can not find light :%d",id);
+            return event_ptr;
+        }
+        event_ptr = create_event(std::to_string(id), et);
+        event_ptr->m_area_id =  light_ptr->m_area_id;
+        event_ptr->m_map_id = light_ptr->m_map_id;
+        event_ptr->x = light_ptr->x;
+        event_ptr->y = light_ptr->y;
+   
+    }
+
+    return event_ptr;
+}
+
 std::shared_ptr<ya_event> event_list::get_event_card(uint32_t card_id, int card_type, EVENT_TYPE ev_type,EVENT_DIS_TYPE edt)
 {
     uint64_t id64 = tool_other::type_id_to_u64(card_type, card_id);

+ 1 - 1
event.h

@@ -7,9 +7,9 @@
 #include<rapidjson/writer.h>
 #include<rapidjson/stringbuffer.h>
 #include<rapidjson/prettywriter.h>
-
 #include<write-copy.h>
 #include "common.h"
+
 struct ya_event
 {
 public:

+ 5 - 1
module_service/module_traffic_light.cpp

@@ -84,7 +84,11 @@ move_stream traffic_light_group::get_stream(const int& cid)
         return ms;
     }
 
-    double dist = p->dist_direct(point(x, y));
+    if(size()<2){
+        return ms;
+    }
+
+    double dist = p->dist_direct(point(x, y)) * traffic_light_manager::instance()->get_scale();
 
     if(dist * updown_dist() > 0){
         ms = move_stream::up_stream;

+ 13 - 6
module_service/module_traffic_light.h

@@ -27,10 +27,12 @@ struct traffic_light: point{
     double m_direct_distance;   // 红绿灯到灯组坐标的距离
     line m_line_group;        // 红绿灯与灯组坐标的连线
     int m_stream;               // 上下行标志,1为上行,2为下行
+    int m_area_id;
+    int m_map_id;
 
     std::shared_ptr<client> m_clt;
 
-    traffic_light(): m_light_id(0), m_group_id(0), m_ip(""), m_state(0), m_port(0), m_phy_light_id(0), m_phy_direction(0), m_rec_time(0), m_special(0), m_direct_distance(0.0), m_stream(0)
+    traffic_light(): m_light_id(0), m_group_id(0), m_ip(""), m_state(0), m_port(0), m_phy_light_id(0), m_phy_direction(0), m_rec_time(0), m_special(0), m_direct_distance(0.0), m_stream(0), m_area_id(0), m_map_id(0)
     {
         m_clt = nullptr;
     }
@@ -97,13 +99,13 @@ struct traffic_light_group: point{
     std::atomic_flag m_owner_flag;  // 控制权
     std::vector<traffic_light_ptr> m_vt_lights;   // 组下红绿灯
     std::array<path, 2> m_path;
-    int m_up_stream_idx;            // 灯组按上行排序的索引值
+    int m_down_stream_idx;            // 灯组按下行排序的索引值
     move_stream m_stream_state;
 
     traffic_light_group(): point(0,0), m_group_id(0), m_scope(0.0), m_manual_time(0), m_auto_interval(0), m_card_id(0), m_map_id(0), m_area_id(0), m_time_stamp(0), m_ctrl_time(0),m_special(false), m_green_light_id(0), m_ctrl_name(""), m_priority(priority_init), m_used(false)
     {
         m_vt_lights.clear();   
-        m_up_stream_idx = 0;
+        m_down_stream_idx = 0;
         m_owner_flag.clear();
         m_stream_state = move_stream::unknown;
     }
@@ -114,7 +116,7 @@ struct traffic_light_group: point{
         m_vt_lights.clear();
         m_used = false;
         m_card_id = 0;
-        m_up_stream_idx = 0;
+        m_down_stream_idx = 0;
         m_owner_flag.clear();
         m_stream_state = move_stream::unknown;
     }
@@ -147,9 +149,9 @@ struct traffic_light_group: point{
         m_priority.store(p);   
     }
 
-    void set_up_stream_idx(const int& v)
+    void set_down_stream_idx(const int& v)
     {
-        m_up_stream_idx = v;
+        m_down_stream_idx = v;
     }
 
     // 获取优先权
@@ -225,6 +227,11 @@ struct traffic_light_group: point{
     // 上行灯与下行灯之间的距离,带方向
     double updown_dist();
 
+    int size()
+    {
+        return m_vt_lights.size();
+    }
+
     void update(double x, double y, double z, int group_id, double scope, int interval, int map_id, int area_id)
     {
         this->x = x;

+ 17 - 2
module_service/module_traffic_light_common.h

@@ -55,7 +55,7 @@ enum light_cmd{
     cmd_card_data,          // 卡数据
 };
 
-enum class move_stream{
+enum move_stream{
     unknown = 0,
     up_stream,
     down_stream,
@@ -67,12 +67,27 @@ struct pos_data: point{
     bool m_bigger;          // 大小车标记
     int32_t m_area_id;      // 区域id
     double m_speed;         // 速度
+    int m_site_id;          // 分站id
     std::list<int> m_light_group;   // 红绿灯组id
 
-    pos_data(): m_card_id(0), m_type(0), m_bigger(false), m_area_id(0), m_speed(0.0)
+    pos_data(): m_card_id(0), m_type(0), m_bigger(false), m_area_id(0), m_speed(0.0), m_site_id(0)
     {
         m_light_group.clear();
     }
+
+    pos_data operator=(const pos_data& p)
+    {
+        this->m_card_id = p.m_card_id;
+        this->m_type    = p.m_type;
+        this->m_bigger  = p.m_bigger;
+        this->m_area_id = p.m_area_id;
+        this->m_speed   = p.m_speed;
+        this->m_site_id = p.m_site_id;
+
+        this->m_light_group = p.m_light_group;
+
+        return *this;
+    }
 };
 
 struct light_message{

+ 111 - 32
module_service/module_traffic_light_manager.cpp

@@ -2,7 +2,9 @@
 #include "db_api/CDBSingletonDefine.h"
 #include <db_api/CDBResultSet.h>
 #include "websocket/constdef.h"
-#include "websocket/wsTimerThread.h"
+//#include "websocket/wsTimerThread.h"
+#include "websocket/ws_common.h"
+#include "event.h"
 
 traffic_light_manager* traffic_light_manager::instance()
 {
@@ -65,6 +67,8 @@ void traffic_light_manager::init_light_from_db(int lid)
         if(it_group != m_unmap_groups.end())
         {
             it_group->second->m_vt_lights.push_back(pl);
+            pl->m_area_id = it_group->second->m_area_id;
+            pl->m_map_id  = it_group->second->m_map_id;
         }
     }
 
@@ -114,7 +118,7 @@ void traffic_light_manager::init_light_group_from_db(int gid)
         }else{
             pg->update(x, y, z, group_id, scope, ai, map_id, area_id);
         }
-        pg->set_up_stream_idx(usi);
+        pg->set_down_stream_idx(usi);
 
         auto ppg = m_map_groups.find(usi);
         if(ppg == m_map_groups.end()){
@@ -130,7 +134,7 @@ void traffic_light_manager::init_light_group_path()
 {
     std::string sql = "select reader_id, tof_flag, b_x, b_y, b_z, e_x, e_y, e_z, spacing_ratio from dat_reader_path_tof_n;";
 
-    std::map<int, std::vector<line_v>> map_path;
+    //std::map<int, std::vector<line_v>> map_path;
 
     std::string error;
     YADB::CDBResultSet res;
@@ -171,12 +175,12 @@ void traffic_light_manager::init_light_group_path()
         point p1(b_x, -b_y, spacing_ratio);
         point p2(e_x, -e_y, spacing_ratio);
 
-        map_path.insert(std::make_pair(reader_id, std::vector<line_v>()));
-        map_path.find(reader_id)->second.push_back(line_v(p1, p2));
+        m_map_path.insert(std::make_pair(reader_id, std::vector<line_v>()));
+        m_map_path.find(reader_id)->second.push_back(line_v(p1, p2));
     }
 
     for(auto itg : m_unmap_groups){
-        for(auto itp : map_path){
+        for(auto itp : m_map_path){
             bool tag = false;
             for(size_t i = 0;i < itp.second.size();i++){
                 if(itp.second[i].contain(point(itg.second->x, itg.second->y),1)){
@@ -190,6 +194,38 @@ void traffic_light_manager::init_light_group_path()
     }
 }
 
+void traffic_light_manager::init_map(int id)
+{
+    std::string sql = "select map_id, scale from dat_map";
+    if(id > 0){
+        sql += " where map_id = " + std::to_string(id);
+    }
+    sql += ";";
+
+    std::string err = "";
+    YADB::CDBResultSet res;
+    
+    sDBConnPool.Query(sql.c_str(), res, err);
+    int count = res.GetRecordCount(err);
+    if(count < 1){
+        log_error("增加或修改失败,数据库中找不到:sql=%s", sql.c_str());
+        return;
+    }
+
+    while(res.GetNextRecod(err)){
+        int map_id = 0;       
+        res.GetField("map_id", map_id, err);
+
+        double scale = 0.0;
+        res.GetField("scale", scale, err);
+
+        set_scale(scale);
+        log_info("init_map: map_id=%d, scale=%.2f", map_id, scale);
+    }
+
+    logn_info(2, "sql:%s" ,sql.c_str());
+}
+
 void traffic_light_manager::init(const int& lgc)
 {
     // 1.先获得红绿灯组数据
@@ -197,6 +233,7 @@ void traffic_light_manager::init(const int& lgc)
     init_light_group_path();
     // 2.再获得红绿灯数据
     init_light_from_db();
+    init_map();
 
     for(hashmap_light::iterator it_light = m_unmap_lights.begin(); it_light != m_unmap_lights.end(); ++it_light){
         if(it_light->second->m_group_id >0){
@@ -236,7 +273,7 @@ void traffic_light_manager::start()
     }else{
         for(auto it = m_unmap_groups.begin(); it != m_unmap_groups.end(); ++it)
         { 
-            log_info("[traffic_light] insert light group into area, area_id=%d", it->second->m_area_id);
+            log_info("[traffic_light] insert light group %d into area, area_id=%d", it->second->m_group_id, it->second->m_area_id);
             m_avoidance_rule->put(it->second);
         }
     }
@@ -289,7 +326,7 @@ void traffic_light_manager::run()
                     handle_manual(it->m_group_id,it->m_light_id, it->m_ctrl_name, it->m_light_state);
                     break;
                 case cmd_card_data:
-                    log_info("[traffic_light] cmd=%d, cid=%d, ctype=%d, bigger=%d, aid=%d, speed=%.2f", it->m_cmd, it->m_pos.m_card_id, it->m_pos.m_type, it->m_pos.m_bigger, it->m_pos.m_area_id, it->m_pos.m_speed);
+                    log_info("[traffic_light] cmd=%d, cid=%d, ctype=%d, bigger=%d, aid=%d, speed=%.2f, sid=%d", it->m_cmd, it->m_pos.m_card_id, it->m_pos.m_type, it->m_pos.m_bigger, it->m_pos.m_area_id, it->m_pos.m_speed, it->m_pos.m_site_id);
                     handle_position(it->m_pos);
                     break;
                 default:
@@ -393,24 +430,6 @@ void traffic_light_manager::manual_ctrl(sio::message::ptr const& data)
         
     // 如果手工控制,否则取消手工控制
     (ctrl == 1)?set_manual(lm):cancel_manual(lm);
-
-    /*for(auto it = vtc.begin(); it != vtc.end(); ++it)
-    {
-        light_message lm;
-        lm.m_group_id = (*it)->get_map()["group_id"]->get_int();
-        lm.m_light_id = (*it)["light_id"]->get_int();
-        lm.m_light_state = (*it)["light_color"]->get_int();
-        lm.m_ctrl_name = (*it)["ctrl_name"]->get_string();
-        int ctrl = (*it)["control"]->get_int();
-        
-        // 如果手工控制,否则取消手工控制
-        (ctrl == 1)?set_manual(lm):cancel_manual(lm);
-    }
-    std::string rd = data->get_map()[JSON_ROOT_KEY_DATA]->get_string();
-
-    log_info("[traffic light] recv web msg: %s", rd.c_str());
-    */
-
 }
 
 void traffic_light_manager::handle_manual(const int& gid, const int& ld, const std::string& name, const int& lc)
@@ -421,6 +440,29 @@ void traffic_light_manager::handle_manual(const int& gid, const int& ld, const s
     }
 }
 
+bool traffic_light_manager::on_path(const std::vector<pos_data>& vtp, const point& p)
+{
+    if(vtp.size() < 2){
+        return false;
+    }
+    int sid = vtp[0].m_site_id;
+
+    auto it = m_map_path.find(sid);
+
+    bool exist = false;
+    if(it != m_map_path.end()){
+        for(int i = 0;i<it->second.size();++i)
+        {
+            if(it->second[i].contain(p, 20)){
+                exist = true;
+                break;
+            }
+        }
+    }
+
+    return exist;
+}
+
 // 红绿灯处理模块入口
 void traffic_light_manager::handle_position(pos_data& p)
 {
@@ -432,12 +474,15 @@ void traffic_light_manager::handle_position(pos_data& p)
     }else if(p.m_type == 2){
         update(p.x, p.y, p.m_card_id);
         m_map_card[p.m_card_id] = p;
+        log_info("[traffic_light] handle position, card_id=%d, x=%.2f, y=%.2f, aid=%d, speed=%.2f, sid=%d", p.m_card_id, p.x, p.y, p.m_area_id, p.m_speed, p.m_site_id);
         // 路口规则
         if(nullptr != m_crossing_rule){
+            m_crossing_rule->put_pos(p);
             m_crossing_rule->handle_rule(p);
         }
 
         if(!p.m_bigger && nullptr != m_avoidance_rule){
+            m_avoidance_rule->put_pos(p);
             m_avoidance_rule->handle_rule(p);
         }
     }
@@ -447,18 +492,14 @@ void traffic_light_manager::handle_position(pos_data& p)
 void traffic_light_manager::set_manual(light_message& msg)
 {
     auto g = m_unmap_groups.find(msg.m_group_id);
-    if(g != m_unmap_groups.end()){
-        int state = ((msg.m_light_state == 8)?9:8);
-        
+    if(g != m_unmap_groups.end()){ 
         for(auto it : g->second->m_vt_lights){
             if(it->m_light_id == msg.m_light_id){
                 send_light_data(msg.m_light_id, 0, msg.m_light_state);
-            }else{
-                send_light_data(msg.m_light_id, 0, state); 
             }
        }
 
-        log_info("[traffic_light] manual ctrl's group info, group_id=%d, light %d's shape is %d, other's shape is %d", msg.m_group_id, msg.m_light_id, msg.m_light_state, state);
+        //log_info("[traffic_light] manual ctrl's group info, group_id=%d, light %d's shape is %d, other's shape is %d", msg.m_group_id, msg.m_light_id, msg.m_light_state, state);
     }
 }
 
@@ -506,3 +547,41 @@ int traffic_light_manager::remove_light_group(const int& id)
 
     return 0;
 }
+
+std::string traffic_light_manager::get_light_state()
+{
+    std::lock_guard<std::mutex> lg(m_vtlg_mutex);
+
+    std::vector<YA::light_state> lights;
+
+    for(auto itg : m_unmap_groups){
+        for(auto itl : itg.second->m_vt_lights){
+            YA::light_state state;
+
+            state.m_group_id = itg.second->m_group_id;
+            state.m_light_id = itl->m_light_id;
+            state.m_light_state = itl->m_state;
+            //state.m_card_id = itg->second->m_card_id;
+
+            lights.push_back(state);
+        }
+    }
+
+    return m_jsBuilder.build_traffic_light(lights);
+}
+
+void traffic_light_manager::visit_light_status()
+{
+    std::lock_guard<std::mutex> lg(m_mutex);
+
+    time_t now = time(0);
+
+    int diff = 0;
+
+    for(auto it : m_unmap_lights){
+        diff = now - it.second->m_rec_time;
+
+        event_tool::instance()->handle_event(OT_DEVICE_LIGHT, ET_LIGHT_ERROR, it.second->m_light_id, LIGHT_TIMEOUT, diff, (diff > LIGHT_TIMEOUT));
+    }
+}
+

+ 23 - 1
module_service/module_traffic_light_manager.h

@@ -11,6 +11,7 @@
 #include "tool_byte.h"
 #include "crc.h"
 #include "protocol.h"
+#include "websocket/wsTimerThread.h"
 
 // 红绿灯管理
 struct traffic_light_manager{
@@ -20,6 +21,7 @@ struct traffic_light_manager{
     void init_light_from_db(int lid = 0);
     void init_light_group_from_db(int gid = 0);
     void init_light_group_path();
+    void init_map(int id = 0);
 
     // 初始化回调信息
     void init(const int& lgc);
@@ -244,8 +246,25 @@ struct traffic_light_manager{
     int remove_light(const int& id);
     int remove_light_group(const int& id);
 
+    void set_scale(const double& scale)
+    {
+        m_map_scale = scale;
+    }
+
+    double get_scale()
+    {
+        return m_map_scale;
+    }
+
+    std::string get_light_state();
+
+    bool on_path(const std::vector<pos_data>& vtp, const point& p);
+
+    void visit_light_status();
+
     private:
     bool m_stop;
+    double m_map_scale = 0.0;
     unsigned int m_light_group_ctrl_num{0};     // 控制红绿灯组数
     std::list<light_message> m_list_data;
     std::mutex m_mutex;
@@ -261,8 +280,11 @@ struct traffic_light_manager{
     hashmap_group m_unmap_groups;
     map_group m_map_groups;
     std::map<uint64_t, pos_data> m_map_card;
-
+    std::map<int, std::vector<line_v>> m_map_path;
     std::map<uint64_t, std::list<traffic_light_group_ptr>> m_vehicle_traffic_groups;
+
+    YA::jsonBuilder m_jsBuilder;//json构造器类
+
 };
 
 #endif

+ 119 - 89
module_service/module_traffic_light_rule.cpp

@@ -37,7 +37,7 @@ traffic_light_ptr rule::find_nearby_light(const point& p, traffic_light_group_pt
     for(auto it = g->m_vt_lights.begin(); it != g->m_vt_lights.end(); ++it)
     {
         traffic_light_ptr tmp = traffic_light_manager::instance()->find_light((*it)->m_light_id);
-        double dt = tmp->dist(p.x, p.y);
+        double dt = tmp->dist(p.x, p.y) * traffic_light_manager::instance()->get_scale();
         if(dt < max){
             max = dt;
             pl = tmp;
@@ -56,7 +56,7 @@ void crossing_rule::change_state(const uint64_t vid, traffic_light_group_ptr g)
         traffic_light_ptr pl = find_nearby_light(point(cp->x, cp->y), g);
         // 设置来车方向为绿灯,其他方向为红灯
         if(nullptr != pl){
-            log_info("[traffic_light] card_id=%lld, light_id=%d", vid, pl->m_light_id);
+            log_info("[traffic_light] card_id=%lld, light_id=%d, light_shape=%d", vid, pl->m_light_id, light_shape::green_all_on);
             g->set_light(pl->m_light_id, light_shape::green_all_on, light_shape::red_all_on);
         }
     }else{
@@ -91,7 +91,7 @@ bool crossing_rule::find_light(const uint64_t& vid, traffic_light_group_ptr g, b
         if(!a){
             if(1 == pl->m_special){
                 // 判断是否在线上
-                if(pl->m_line_group.contain(cp->x, cp->y, 0.5)){
+                if(pl->m_line_group.contain(cp->x, cp->y, 5)){
                     // 判断行车方向
                     double d = cp->m_speed * pl->m_direct_distance;
                     if(d < 0){
@@ -101,7 +101,7 @@ bool crossing_rule::find_light(const uint64_t& vid, traffic_light_group_ptr g, b
             }
         }else{
             // 判断是否在线上
-            if(pl->m_line_group.contain(cp->x, cp->y, 1.0)){
+            if(pl->m_line_group.contain(cp->x, cp->y, 5.0)){
                 double d = cp->m_speed * pl->m_direct_distance;
                 if(d < 0){
                     return true;
@@ -132,7 +132,7 @@ bool crossing_rule::handle_crossing(traffic_light_group_ptr group)
 
     // 查找一定范围的车辆
     std::vector<uint64_t> vtl = traffic_light_manager::instance()->find_nearby_vehicle(point(static_cast<int>(group->x), static_cast<int>(group->y)), group->m_scope, group->m_group_id);
-    log_info("[traffic_light] handle crossing rule.gid=%d, group_scope=%.2f, vehicle's num=%d", group->m_group_id, group->m_scope, vtl.size());
+    //log_info("[traffic_light] handle crossing rule.gid=%d, group_scope=%.2f, vehicle's num=%d", group->m_group_id, group->m_scope, vtl.size());
     if(vtl.empty()){
         if(group->m_card_id > 0 && group->m_priority == priority_crossing)
         {
@@ -232,11 +232,11 @@ bool crossing_rule::avoidance_by_level(traffic_light_group_ptr& group)
     }
     
     if(vt.size() == 1 && vt[0] == group->m_card_id){
-        log_info("[traffic_light] group is controlled, gid=%d, cid=%d", group->m_group_id, group->m_card_id);
+        log_info("[traffic_light] crossing_rule::avoidance_by_level, group is controlled, gid=%d, cid=%d", group->m_group_id, group->m_card_id);
         return false;
     }
 
-    log_info("[traffic_light] handle avoidance_by_level, gid=%d, x=%.2f, y=%.2f, scope=%.2f, ctrl_cid=%d, ivehicle's size=%d", group->m_group_id, group->x, group->y, group->m_scope, group->m_card_id, vt.size());
+    log_info("[traffic_light] crossing_rule::avoidance_by_level, gid=%d, x=%.2f, y=%.2f, scope=%.2f, ctrl_cid=%d, ivehicle's size=%d", group->m_group_id, group->x, group->y, group->m_scope, group->m_card_id, vt.size());
 
     if(group->m_card_id > 0 && get_vehicle_state(group->m_card_id)){
         //检查是否释放控制权
@@ -361,6 +361,8 @@ bool crossing_rule::avoidance_by_updown(traffic_light_group_ptr& group)
             }
         }
     }
+    
+    log_info("[traffic_light] handle avoidance_by_updown, gid=%d, control_card_id=%d, exist_up_stream_vehicle=%s", group->m_group_id, group->m_card_id, (exist_up_stream?"true":"false"));
 
     if(exist_up_stream || group->m_card_id > 0){
         // erase vehicles that's state of down_stream
@@ -370,9 +372,10 @@ bool crossing_rule::avoidance_by_updown(traffic_light_group_ptr& group)
                     }else{
                         return false;
                     }
-                    }));
+                    }), vt.end());
 
         if(vt.empty()){
+            //log_info("[traffic_light] handle avoidance_by_updown")
             return false;
         }
     }
@@ -429,6 +432,11 @@ bool crossing_rule::avoidance_by_updown(traffic_light_group_ptr& group)
 void crossing_rule::handle_rule(pos_data& p)
 {
     //log_info("[traffic_light] crossing_rule::handle_rule, group's size=%d", m_vt_group.size());
+    if(m_pos.size()<2){
+        log_warn("[traffic_light] pos_data's size = %d", m_pos.size());
+        return;
+    }
+    
     for(auto& it : m_vt_group){
         // 获取控制权
         it->get_turn();
@@ -438,7 +446,7 @@ void crossing_rule::handle_rule(pos_data& p)
         while(true){
             if(priority_manual_ctrl == priority){
                 flag = handle_manual_ctrl(it);
-                log_info("[traffic_light] crossing_rule::handle_rule, after call handle_manual_ctrl, flag=%d", flag);
+                //log_info("[traffic_light] crossing_rule::handle_rule, after call handle_manual_ctrl, flag=%d", flag);
                 if(flag){
                     break;
                 }
@@ -446,7 +454,7 @@ void crossing_rule::handle_rule(pos_data& p)
 
             if(priority <= priority_avoidance){
                 flag = handle_avoidance(it);
-                log_info("[traffic_light] crossing_rule::handle_rule, after call handle_avoidance, flag=%d", flag);
+                //log_info("[traffic_light] crossing_rule::handle_rule, after call handle_avoidance, flag=%d", flag);
                 if(flag){
                     break;
                 }
@@ -454,7 +462,7 @@ void crossing_rule::handle_rule(pos_data& p)
 
             if(priority <= priority_crossing){
                 flag = handle_crossing(it);
-                log_info("[traffic_light] crossing_rule::handle_rule, after call handle_crossing, flag=%d", flag);
+                //log_info("[traffic_light] crossing_rule::handle_rule, after call handle_crossing, flag=%d", flag);
                 if(flag){
                     break;
                 }
@@ -478,7 +486,7 @@ vt_traffic_group avoidance_rule::find_group(const pos_data& p)
     return find_group(point(p.x, p.y), p.m_area_id, p.m_speed, p);
 }
 
-vt_traffic_group avoidance_rule::find_group(const point& po , int area_id, double  speed, const pos_data& pd)
+vt_traffic_group avoidance_rule::find_group(const point& po , int area_id, double speed, const pos_data& pd)
 {
     vt_traffic_group llist;
 
@@ -490,6 +498,10 @@ vt_traffic_group avoidance_rule::find_group(const point& po , int area_id, doubl
     vt_traffic_group vg = m_map_area_group[area_id];
 
     double dist = 0.0;
+    double scale = traffic_light_manager::instance()->get_scale();
+
+    double alpha = 0.0;
+    int gid = 0;
     for(std::size_t i = 0; i < vg.size(); ++i){
         traffic_light_group_ptr pg = vg[i];
         if(nullptr == pg){
@@ -501,53 +513,50 @@ vt_traffic_group avoidance_rule::find_group(const point& po , int area_id, doubl
             log_info("[traffic_light] card_id=%lld was control light group, gid=%d", pd.m_card_id, vg[i]->m_group_id);
             continue;
         }
-
         // 求灯组到车辆的距离(车辆在灯组的左下方,则距离值取反)
-        dist = vg[i]->dist_direct(po.x, po.y);
-        // 车辆在灯组左边或下边
-        log_info("[traffic_light] avoidance_rule::find_group, area_id=%d, area_group=%d, dist=%.2f", area_id, vg.size(), dist);
-        if(dist <= 0){
-            // 速度方向与前进方向一致
-            if(speed > 0){
-                // 车辆到灯组的距离小于指定距离
-                if(vg[i]->dist(po.x, po.y) <= g_max_scope){
-                    llist.push_back(vg[i]);
-                }
-
-                // 紧挨着的一个灯组到车距离小于指定阈值
-                if(i + 1 < vg.size()){
-                    if(vg[i+1]->dist(po.x, po.y) <= g_max_scope){
-                        llist.push_back(vg[i+1]);
-                    }
-                }
-            }else if(speed < 0){
-                // 速度方向与前进方向不一致,判断运动方向的灯组是否在可控范围
-                if(i >= 1 && vg[i - 1]->dist(po.x, po.y) <= g_max_scope){
-                    llist.push_back(vg[i-1]);
-                }
-                if(i >= 2 && vg[i-2]->dist(po.x, po.y) <= g_max_scope){
-                    llist.push_back(vg[i-2]);
-                }
+        dist = m_pos[1].dist_direct(vg[i]->x, vg[i]->y) * scale;
+        point vp1(vg[i]->x - m_pos[0].x, vg[i]->y - m_pos[0].y), vp2(m_pos[1].x - m_pos[0].x, m_pos[1].y - m_pos[0].y);
+        int f1 = (vg[i]->x > m_pos[0].x ? 1 : -1);
+        int f2 = (m_pos[1].x > m_pos[0].x ? 1: -1);
+        if(f1*f2 > 0 && fabs(dist) < vg[i]->m_scope)
+        {
+            double tmp = (vp1.x*vp2.x + vp1.y*vp2.y)/(sqrt(vp1.x*vp1.x + vp1.y+vp1.y) * sqrt(vp2.x*vp2.x + vp2.y*vp2.y));
+            tmp = (tmp>0?(tmp>1?fabs(tmp-1):tmp):(tmp>-1?fabs(tmp):fabs(tmp+1)));
+            if(tmp < alpha){
+                alpha = tmp;
+                gid = vg[i]->m_group_id;
             }
-
-            break;
+            llist.push_back(vg[i]);
+            log_info("[traffic_light] avoidance_rule::find_group, possiable light_group_id=%d, alpha=%.2f, area_id=%d, area_light_group_size=%d, scope=%.2f, dist=%.2f, min_alpha=%.2f, speed=%.2f, direction=%d", vg[i]->m_group_id, tmp, area_id, vg.size(), vg[i]->m_scope, dist, alpha, speed, f1*f2);    
         }
-
-        log_info("[traffic_light] the vehicle is in light group's left or down side.");
     }
 
-    // 车辆在灯组右边或上边
-    if(dist > 0 && speed < 0){
-        std::size_t i = vg.size();
-        if(i >= 1 && vg[i-1]->dist(po.x, po.y) <= g_max_scope){
-            llist.push_back(vg[i-1]);
-        }
-        if(i >= 2 && vg[i-2]->dist(po.x, po.y) <= g_max_scope){
-            llist.push_back(vg[i-2]);
-        }
-        log_info("[traffic_light] the vehicle is in light group's right or up side");
+    if(gid > 0){
+        llist.erase(std::remove_if(llist.begin(), llist.end(), [&](const traffic_light_group_ptr& g){
+                    if(g->m_group_id != gid){
+                        return true;
+                    }else{
+                        return false;
+                    }
+                    }), llist.end());
     }
 
+    //检查接收基站所在路径有没有此灯组,没有则删除
+    std::vector<pos_data> vtp;
+    vtp.insert(vtp.begin(), m_pos.begin(), m_pos.end());
+
+    llist.erase(std::remove_if(llist.begin(), llist.end(), [&](const traffic_light_group_ptr& g){
+                    if(!traffic_light_manager::instance()->on_path(vtp, point(g->x, g->y))){
+                         log_info("[traffic_light] the %d light group is not on %d site path.", g->m_group_id, vtp[0].m_site_id);
+                         return true;
+                    }else{
+                        log_info("[traffic_light] the %d light group is on %d site path.", g->m_group_id, vtp[0].m_site_id);
+                        return false;
+                    }
+                }),
+            llist.end()
+            );
+  
     return std::move(llist);
 }
 
@@ -585,10 +594,6 @@ bool avoidance_rule::get_vehicle(const pos_data& p, vt_traffic_group& vg)
 
     std::set_intersection(vt1.begin(), vt1.end(), vt2.begin(), vt2.end(), std::back_inserter(vti));
 
-    if(vti.empty()){
-        return false;
-    }
-
     // 筛选出符合条件的车辆,离第一个红绿灯距离进行排序
     vti.erase(std::remove_if(vti.begin(), vti.end(), [&](const uint64_t& vid) -> bool {
                 pos_data* tp = traffic_light_manager::instance()->get_position(vid);
@@ -664,7 +669,7 @@ void avoidance_rule::change_group(const traffic_light_group_ptr& g, const point&
     if(nullptr == pl){
         return;
     }
-    log_info("[traffic_light] change light's status in %d group", g->m_group_id);
+    log_info("[traffic_light] change light's status in the %d's light group", g->m_group_id);
     // 2.获取灯组中临近车辆的灯id
     g->m_green_light_id = pl->m_light_id;
     g->get_turn();
@@ -674,6 +679,19 @@ void avoidance_rule::change_group(const traffic_light_group_ptr& g, const point&
     g->release_turn();
 }
 
+void avoidance_rule::change_group(const traffic_light_group_ptr& g, const move_stream& s, const int& lc, const int& lcr)
+{
+    g->get_turn();
+    for_each(g->m_vt_lights.begin(), g->m_vt_lights.end(), [&](traffic_light_ptr& l){ 
+            if(l->m_stream == s){
+                g->m_green_light_id = l->m_light_id;
+                g->set_light(l->m_light_id, lc, lcr);
+            }            
+            });
+
+    g->release_turn();
+}
+
 bool avoidance_rule::is_different(traffic_light_group_ptr g, const point& p, const int& lc, const int& lcr)
 {
     bool b = false;
@@ -688,24 +706,29 @@ bool avoidance_rule::is_different(traffic_light_group_ptr g, const point& p, con
 
 void avoidance_rule::handle_rule(pos_data& p)
 {
+    if(m_pos.size() < 2){
+        log_warn("[traffic_light] pos_data's size = %d", m_pos.size());
+        return;
+    }
+
     vt_traffic_group llist;
 
     if(p.m_card_id == 0|| p.m_type == 0){
         return;
     }
 
-    log_info("[traffic_light] avoidance_rule::handle_rule, group's size=%d, area_id=%d", m_map_area_group.size(), p.m_area_id);
+    log_info("[traffic_light] avoidance_rule::handle_rule, group's size=%d, area_id=%d his_pos's size=%d, pos0.x=%.2f, pos0.y=%.2f, pos1.x=%.2f, pos2.y=%.2f", m_map_area_group.size(), p.m_area_id, m_pos.size(), m_pos[0].x, m_pos[0].y, m_pos[1].x, m_pos[1].y);
     auto it = m_map_area_group.find(p.m_area_id);
     if(it != m_map_area_group.end()){
         // 根据车卡的定位坐标以及定位区域信息获取红绿灯组
         vt_traffic_group vtg = find_group(point(p.x, p.y), p.m_area_id, p.m_speed, p);
-        log_info("[traffic_light] handle avoidance rule, area has light, area_id=%d, card_id=%d, light_group's size=%d", p.m_area_id, p.m_card_id, vtg.size());
+        //log_info("[traffic_light] handle avoidance rule, area has light, area_id=%d, card_id=%d, light_group's size=%d", p.m_area_id, p.m_card_id, vtg.size());
         if(vtg.size() == 0){
             // 所在区域没有可以控制的红绿灯组
             switch(p.m_light_group.size())
             {
                 case 1:
-                    // 当前车辆控制的路口为1个,释放该口控制
+                    // 当前车辆控制的路口为1个,释放该口控制
                     erase(true, p, llist);
                     break;
                 case 2:
@@ -720,7 +743,7 @@ void avoidance_rule::handle_rule(pos_data& p)
             {
                 case 0:
                     // 当前卡没有绑定红绿灯组,绑定此灯组,并设置灯组颜色为绿色
-                    insert(vtg[0], p, llist, green, red);
+                    insert(vtg[0], p, llist, light_shape::green_all_on, light_shape::red_all_on);
                     break;
                 case 1:
                     //当前卡绑定了1个红绿灯组
@@ -728,7 +751,7 @@ void avoidance_rule::handle_rule(pos_data& p)
                         // 检查当前卡绑定的红绿灯组与区域找到的是不是同一个
                         // 不是,释放之前的绑定,再绑定新灯组
                         erase(true, p, llist);
-                        insert(vtg[0], p, llist, green, red);
+                        insert(vtg[0], p, llist, light_shape::green_all_on, light_shape::red_all_on);
                     }else{
                         // 当前卡绑定的红绿灯组与区域找到的是同一个
                         traffic_light_ptr pl = find_nearby_light(point(p.x, p.y), vtg[0]);
@@ -745,40 +768,40 @@ void avoidance_rule::handle_rule(pos_data& p)
                 // 第一个绑定的红绿灯组与区域找到的是同一个,删除第二个
                 erase(false, p, llist);
                 if(g->get_priority() <= priority_avoidance){
-                    change_group(g, point(p.x, p.y), green, red);
+                    change_group(g, point(p.x, p.y), light_shape::green_all_on, light_shape::red_all_on);
                     llist.push_back(g);
                 }
             }else if(p.m_light_group.back() == g->m_group_id){
                 // 第二个绑定的红绿灯组与区域找到的是同一个,删除第一个
                 erase(true, p, llist);
                 if(g->get_priority() <= priority_avoidance){
-                    change_group(g, point(p.x, p.y), green, red);
+                    change_group(g, point(p.x, p.y), light_shape::green_all_on, light_shape::red_all_on);
                     llist.push_back(g);
                 }
             }else{
                 // 两个都不是,全部删除
                 erase(true, p, llist);
                 erase(false, p, llist);
-                insert(g, p, llist, green, red);
+                insert(g, p, llist, light_shape::green_all_on, light_shape::red_all_on);
             }
         }else if(2 == vtg.size()){
             // 所在区域存在两个红绿灯组,巷道相遇逻辑
             // 判断两个灯组中是否有车
             bool b = get_vehicle(p, vtg);
-            light_color la, lb;
+            int la, lb;
             if(b){
-                la = red;
-                lb = spark;
+                la = light_shape::red_all_on;
+                lb = light_shape::red_spark;
             }else{
-                la = green;
-                lb = red;
+                la = light_shape::green_all_on;
+                lb = light_shape::red_all_on;
             }
 
             switch(p.m_light_group.size()){
                 case 0:
                     // 当前卡没有绑定红绿灯组,绑定2个灯组
                     insert(vtg[0], p, llist, la, lb);
-                    insert(vtg[1], p, llist, green, spark);
+                    insert(vtg[1], p, llist, light_shape::green_all_on, light_shape::green_spark);
                     break;
                 case 1:
                     // 当前卡有绑定1个红绿灯组,更新
@@ -787,11 +810,11 @@ void avoidance_rule::handle_rule(pos_data& p)
                             change_group(vtg[0], point(p.x, p.y), la, lb);
                             llist.push_back(vtg[0]);
                         }
-                        insert(vtg[1], p, llist, green, spark);
+                        insert(vtg[1], p, llist, light_shape::green_all_on, light_shape::green_spark);
                     }else if(p.m_light_group.front() == vtg[1]->m_group_id){
                         if(vtg[1]->get_priority() <= priority_avoidance)
                         {
-                            change_group(vtg[1], point(p.x, p.y), green, spark);
+                            change_group(vtg[1], point(p.x, p.y), light_shape::green_all_on, light_shape::green_spark);
                             llist.push_back(vtg[1]);
                         }
                         p.m_light_group.push_front(vtg[0]->m_group_id);
@@ -804,7 +827,7 @@ void avoidance_rule::handle_rule(pos_data& p)
                         // 两个都不相等
                         erase(false, p, llist);
                         insert(vtg[0], p, llist, la, lb);
-                        insert(vtg[1], p, llist, green, spark);
+                        insert(vtg[1], p, llist, light_shape::green_all_on, light_shape::green_spark);
                     }
                     break;
                 case 2:
@@ -821,7 +844,7 @@ void avoidance_rule::handle_rule(pos_data& p)
                                     if(is_different(vtg[0], point(p.x, p.y), la, lb)){
                                         llist.push_back(vtg[0]);
                                     }
-                                    if(is_different(vtg[1], point(p.x, p.y), green, spark)){
+                                    if(is_different(vtg[1], point(p.x, p.y), light_shape::green_all_on, light_shape::red_all_on)){
                                         llist.push_back(vtg[1]);
                                     }
                                 }else{
@@ -831,7 +854,7 @@ void avoidance_rule::handle_rule(pos_data& p)
                                         llist.push_back(vtg[0]);
                                     }
                                     if(vtg[1]->get_priority() <= priority_avoidance){
-                                        change_group(vtg[1], point(p.x, p.y), green, spark);
+                                        change_group(vtg[1], point(p.x, p.y), light_shape::green_all_on, light_shape::green_spark);
                                         llist.push_back(vtg[1]);
                                     }
                                     p.m_light_group.push_back(vtg[0]->m_group_id);
@@ -841,25 +864,32 @@ void avoidance_rule::handle_rule(pos_data& p)
                                     change_group(vtg[0], point(p.x, p.y), la, lb);
                                     llist.push_back(vtg[0]);
                                 }
-                                insert(vtg[1], p, llist, green, spark);
+                                insert(vtg[1], p, llist, light_shape::green_all_on, light_shape::green_spark);
                             }
-                        }
-                        else
-                        {
-                            if(itt != p.m_light_group.end()){
-                                if(p.m_light_group.front() == vtg[1]->m_group_id){
-                                    erase(false, p, llist);
-                                }else{
+                            else
+                            {
+                                if(itt != p.m_light_group.end()){
+                                    if(p.m_light_group.front() == vtg[1]->m_group_id){
+                                        erase(false, p, llist);
+                                    }else{
+                                        erase(true, p, llist);
+                                    }
                                     erase(true, p, llist);
+                                    erase(true, p, llist);
+                                    insert(vtg[0], p, llist, la, lb);
+                                    insert(vtg[1], p, llist, light_shape::green_all_on, light_shape::green_spark);
                                 }
-                                erase(true, p, llist);
-                                erase(true, p, llist);
-                                insert(vtg[0], p, llist, la, lb);
-                                insert(vtg[1], p, llist, green, spark);
                             }
                         }
+                        break;     
                     }
-                    break;     
+            }
+        }
+        else if(vtg.size() > 2){
+            log_info("[traffic_light] control light group's size = %d", vtg.size());
+            for(auto it : vtg){
+                move_stream s = it->get_stream(p.m_card_id);
+                change_group(it, s, light_shape::green_all_on, light_shape::green_spark);
             }
         }
     }else{

+ 23 - 2
module_service/module_traffic_light_rule.h

@@ -9,6 +9,7 @@
 #include <condition_variable>
 #include "module_traffic_light_common.h"
 #include "module_traffic_light.h"
+#include <boost/circular_buffer.hpp>
 
 using vt_traffic_group = std::vector<traffic_light_group_ptr>;
 using mp_traffic_group = std::map<int, vt_traffic_group>;
@@ -21,6 +22,7 @@ struct rule{
     virtual void handle_rule(pos_data& p) = 0;
     virtual void put(traffic_light_group_ptr tlp) = 0;
     virtual void put(vt_traffic_group&& vc) = 0;
+    virtual void put_pos(const pos_data data) = 0;
     // 闯红灯检查
     virtual std::shared_ptr<run_red_light> check_run_red_light(pos_data& p) = 0;
     // 车子按距离红绿灯组坐标点排序
@@ -33,7 +35,10 @@ struct rule{
 
 // 路口规则
 struct crossing_rule: rule{
-    crossing_rule(){}
+    crossing_rule()
+    {
+        m_pos.set_capacity(2);
+    }
     ~crossing_rule(){}
 
     // 
@@ -65,6 +70,11 @@ struct crossing_rule: rule{
         m_vt_group = vc;
     }
 
+    void put_pos(const pos_data data)
+    {
+        m_pos.push_back(data);
+    }
+
     int size()
     {
         return m_vt_group.size();
@@ -73,12 +83,16 @@ struct crossing_rule: rule{
     private:
         // 灯组
         vt_traffic_group m_vt_group;
+        boost::circular_buffer<pos_data> m_pos; 
 };
 
 // 避让规则
 struct avoidance_rule: rule{
     public:
-        avoidance_rule(){}
+        avoidance_rule()
+        {
+            m_pos.set_capacity(2);           
+        }
         ~avoidance_rule(){}
 
         void handle_rule(pos_data& p);
@@ -86,6 +100,7 @@ struct avoidance_rule: rule{
         void insert(traffic_light_group_ptr g, pos_data& p, vt_traffic_group& vg, const int lc, const int lcr);
         // 改变点p定位附近灯组的状态,满足条件的灯状态改为lc,否改为lcr
         void change_group(const traffic_light_group_ptr& g, const point& p, const int& lc, const int& lcr);
+        void change_group(const traffic_light_group_ptr& g, const move_stream& s, const int& lc, const int& lcr);
         // 把车卡从灯组控制中解绑
         void erase(bool a, pos_data& p, vt_traffic_group& vg);
         // 根据车辆与灯组的位置关系,查找灯组
@@ -112,6 +127,11 @@ struct avoidance_rule: rule{
                 m_map_area_group[x->m_area_id].push_back(x);
             }
         }
+
+        void put_pos(const pos_data data)
+        {
+            m_pos.push_back(data);    
+        }
     
         int size()
         {
@@ -120,6 +140,7 @@ struct avoidance_rule: rule{
 
     private:
         mp_traffic_group m_map_area_group;
+        boost::circular_buffer<pos_data> m_pos;
 };
 
 using hashmap_light = std::unordered_map<int, traffic_light_ptr>;

+ 12 - 0
module_service/module_web.cpp

@@ -89,6 +89,18 @@ void module_web::response_login()
         tool_json::push_back(nodes, event_list::evs_to_json(arr), allocator);
     }
 
+    //所有红绿灯信息
+    str = traffic_light_manager::instance()->get_light_state();
+    if(!str.empty()){
+        tool_json::push_back(nodes, str, allocator);
+    }
+
+    // 防碰撞告警
+    str = module_call::instance()->get_json_anti_collision();
+    if(!str.empty()){
+        tool_json::push_back(nodes, str, allocator);
+    }
+
     if(nodes.Size()>0)
     {
         doc.AddMember(JSON_ROOT_KEY_CMD,JSON_CMD_VALUE_RESPONSE_ALL_DATA, allocator);

+ 11 - 2
net-service.cpp

@@ -36,6 +36,8 @@ void net_service::on_timer()
 {
 	visit_site_status vss;
 	sit_list::instance()->accept(vss);
+
+    traffic_light_manager::instance()->visit_light_status();
 }
 
 void net_service::on_connect(const std::shared_ptr<client>& clt)
@@ -210,6 +212,8 @@ void net_service::on_message(const std::shared_ptr<client> &clt,const char*data,
                     if(!site_ptr){
                         logn_error(1,"在全局分站列表中找不到分站:%d", site_id);
                         break;
+                    }else{
+                        logn_info(3, "[pdoa] site_id:%d, x:%.4f, y:%.4f", site_ptr->m_id, site_ptr->x, site_ptr->y);
                     }
                     
                     if(clt->type() != 2){
@@ -237,8 +241,12 @@ void net_service::on_message(const std::shared_ptr<client> &clt,const char*data,
                         t->m_cmd_code = cmd;
                         t->m_hash_id = m.m_card_id;
                         pdoa = get_pdoa(m.m_poa, site_ptr->m_pdoa_offset);
-                        m_loc_worker->request(t);
                         logn_info(3, "[pdoa] site_id=%d, card_id=%d, ct=%d, dist=%.3f, rav=%d, poa1=%.4f, poa2=%.4f, poa3=%.4f, pdoa=%.4f, pdoa_offset=%.4f", site_id, m.m_card_id, m.m_card_ct, dist, m.m_rav, m.m_poa[0], m.m_poa[1], m.m_poa[2], pdoa, site_ptr->m_pdoa_offset);
+                     
+                        if(m.m_poa[1] == 10.0){
+                            continue;
+                        }
+                        m_loc_worker->request(t);
                     }
                 }
                 break;
@@ -366,7 +374,8 @@ void net_service::on_message(const std::shared_ptr<client> &clt,const char*data,
                     uint8_t status = 0;
                     is>>id>>stamp>>status;
                     logn_info(4, "[traffic_light] light heart message, light_id=%d, stamp=%d, status=%d", id, stamp, status);
-                   
+                    logn_info(1, "红绿灯数据 : light_id=%d, ct=%d", id, stamp);
+
                     auto light_ptr = traffic_light_manager::instance()->get(id);
                     if(!light_ptr)
                     {

+ 3 - 9
visit.cpp

@@ -17,7 +17,7 @@ struct card_list:single_base<card_list,int,std::shared_ptr<card>>
 		for(std::pair<int,std::shared_ptr<card>> me:m_map)
 		{
 			v.visit(me.second);
-			printf("====\n");
+			//printf("====\n");
 		}
 	}
 };
@@ -26,7 +26,7 @@ struct visit_log:visitor<std::shared_ptr<card>>
 {
 	bool visit(std::shared_ptr<card> c)
 	{
-		printf("vist :::::::%d\n",c->id);
+	    //printf("vist :::::::%d\n",c->id);
 		return true;
 	}
 };
@@ -36,14 +36,8 @@ void run()
 {
 	visit_log vl;
 	card_list::instance()->accept(vl);
-	/*
-	while(true)
-	{
-		printf("111111111111\n");
-		std::this_thread::sleep_for(std::chrono::milliseconds(500));
-	}
-	*/
 }
+
 int main()
 {
 	std::vector<std::shared_ptr<card_list>> v;

+ 6 - 1
websocket/jsonBuilder.cpp

@@ -104,7 +104,8 @@ namespace YA
 		Array.PushBack( tmp_object, Allocator );
 
 		//6 工作时长
-		tmp_object.SetDouble( CardPos.work_time );
+		tmp_object.SetDouble(CardPos.z);
+        //tmp_object.SetDouble( CardPos.work_time );
 		Array.PushBack( tmp_object, Allocator );
 
 		//7 地图编号
@@ -410,6 +411,10 @@ namespace YA
 
 	std::string jsonBuilder::BuildCardPos( const std::map<uint64_t, _CARD_POS_>& CardPosList )
 	{
+        if(CardPosList.empty()){
+            return "";
+        }
+
         static bool p2s=false;
         p2s=p2s?false:true;
 		rapidjson::StringBuffer sb;

+ 0 - 1
websocket/jsonCommon.h

@@ -6,7 +6,6 @@ jason公共头文件
 V 1.0.0
 
 * @author
-王益俊
 
 * @date
 创建时间:  2018-04-19\n

+ 8 - 2
websocket/wsTimerThread.cpp

@@ -68,7 +68,13 @@ namespace YA
 		if(__CardPosList.empty())
 		    return;
 		__CardPosList.copy( CardPosList );
-		std::string jsCardPos = __jsBuilder.BuildCardPos( CardPosList );
+     
+        std::string jsCardPos = __jsBuilder.BuildCardPos( CardPosList );
+
+        if(jsCardPos == ""){
+            return;
+        }
+
 		swsClientMgr.send( JSON_CMD_VALUE_PUSH, jsCardPos );
 	}
 
@@ -106,7 +112,7 @@ namespace YA
             return;
         }
         std::vector<light_state> lights = light_state_list;
-        log_info("[light_test] light_state's size=%d, copy=%d", light_state_list.size(), lights.size());
+        //log_info("[light_info] light_state's size=%d, copy=%d", light_state_list.size(), lights.size());
         std::string json_light = __jsBuilder.build_traffic_light(lights);
         swsClientMgr.send(JSON_CMD_VALUE_PUSH, json_light);
         light_state_list.erase(light_state_list.begin(), light_state_list.end());

+ 0 - 1
websocket/ws_common.h

@@ -6,7 +6,6 @@
  V 1.0.0
 
  * @author
- 王益俊
 
  * @date
  创建时间:  2018-08-17\n

+ 1 - 3
worker.cpp

@@ -5,9 +5,7 @@
 #include <atomic>
 #include <memory>
 #include <thread>
-
 #include <ev++.h>
-
 #include "log.h"
 #include "worker.h"
 #include "message.h"
@@ -209,7 +207,7 @@ struct worker_thread: loop_thread ,visitor<std::shared_ptr<card_location_base>>
 				t.destroy();
                 break;
             case CHAR_LOCATEDATA_PDOA:      // pdoa实时定位数据
-                log_info("card loc message: 0x%04X", t.m_cmd_code);
+                //log_info("card loc message: 0x%04X", t.m_cmd_code);
                 card_list::instance()->on_message(this, t.body<message_pdoa_locinfo>(), false);
                 t.destroy();
                 break;