Browse Source

修改分站路径初始化处理,允许定义以下路径,需要路径连续,分站不可距离路径太远(10pt),不再限制ant-flag在[-2,2]之间
1.
------------------
^
2.
\
\.------------------
^
3.
\
\.--------.--------.\
^ \
4.
\
\.----------------.\
^ \
5.
\
\.--------
^

6.
-----------
^

zzj 6 years ago
parent
commit
3bf8e45be3
9 changed files with 510 additions and 506 deletions
  1. 301 115
      ant.cpp
  2. 19 78
      ant.h
  3. 3 2
      card.cpp
  4. 24 6
      line.h
  5. 1 1
      message.h
  6. 1 8
      module_service/module_meta_date_changed.cpp
  7. 1 4
      select_tool.cpp
  8. 158 290
      test.cpp
  9. 2 2
      znet.cpp

+ 301 - 115
ant.cpp

@@ -17,8 +17,8 @@ int site::index()const
 site::site(int id)
 	:m_algo(0)
 	,m_num_dims(0)
-    ,m_id(id)
-    ,m_path_empty(true)
+	,m_id(id)
+	,m_path_empty(true)
 {
 	m_time=time(0);
 }
@@ -28,139 +28,325 @@ const algo_config&site::config()const
 	return g_config[index()];
 }
 
-bool visit_site_status::visit(std::shared_ptr<site> s)
+void ant::set_path(const std::vector<line_v>&v_line,std::vector<line_v>::const_iterator itm)
 {
-	time_t now=time(0);
-	int diff = now-s->m_time;
-	event_tool::instance()->handle_event(OT_DEVICE_READER,ET_READER_ERROR,s->m_id,READER_TIMEOUT,diff,[diff](){return diff>READER_TIMEOUT;});
-	return true;
+	auto it=itm;
+	for(int i=0;i<2 && it!=v_line.end();++it,++i)
+		m_path[0][i]=*it;
+
+	it=itm-1;
+	for(int i=0;i<2 && it>=v_line.begin();--it,++i)
+	{
+		m_path[1][i]=*it;
+		m_path[1][i].swap_point();
+	}
+
+	for(auto&p:m_path)
+	{
+		log_info("site-path: %s",p.to_str().c_str());
+	}
 }
 
-void sit_list::read_ant_path(int id)
+void ant::set_path(const std::vector<line_v>&v_line_)
 {
-     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::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++)
+	{
+		double d=it->as_line().dist(*this);
+		if(d<dist)
+		{
+			dist=d;
+			min_it=it;
+		}
+	}
+
+	if(min_it==vl.end())
+	{
+		log_error("分站路径距离分站太远site_id=%d",m_id);
+		return;
+	}
 
-     if(-1 == id)
-     {
-         sql.append(";");
-     }
-     else
-     {
-         sql.append(" where reader_id=");
-         sql.append(std::to_string(id));
-         sql.append(";");
+	if(abs(min_it->v[0].dist(*this)-dist)<1)
+	{
+		set_path(vl,min_it);
+	}
+	else if(abs(min_it->v[1].dist(*this)-dist)<1)
+	{
+		set_path(vl,min_it+1);
+	}
+	else
+	{
+		point proj=min_it->projection(*this);
+		vl.insert(min_it+1,line_v(proj,min_it->v[1]));
+		min_it->set_point(1,proj);
+
+		if(min_it->v[0].z)//slope ..555
+		{
+			double slope=min_it->v[0].z;
+			double len_a=min_it->v[0].dist((min_it+1)->v[1]);
+			double len_0=slope*min_it->length()/len_a;
+			double len_1=slope-len_0;
+			
+			min_it->v[0].z=min_it->v[1].z=len_0;
+			(min_it+1)->v[0].z=(min_it+1)->v[1].z=len_1;
+		}
+
+		set_path(vl,min_it+1);
+	}
+}
 
-         std_debug("修改path sql=%s", sql.c_str());
-         log_info("修改path sql=%s", sql.c_str());
-     }
+void site::set_path(const std::vector<line_v>&v_line)
+{
+	if(v_line.empty())
+		return;
+
+	const auto&find_line=[](const point&pt,int first,std::vector<line_v>&vl){
+		for(auto it=vl.begin();it!=vl.end();it++)
+		{
+			if(it->v[first].dist(pt)<1)
+				return it;
+			if(it->v[first?0:1].dist(pt)<1)
+			{
+				point p=it->v[0];
+				it->v[0]=it->v[1];
+				it->v[1]=p;
+				return it;
+			}
+		}
+
+		return vl.end();
+	};
+	
+	//构造一个首尾相连的结构
+
+	std::vector<line_v> vl(v_line.begin()+1,v_line.end());
+	std::vector<line_v> target(v_line.begin(),v_line.begin()+1);
+#if 0
+	target[0][0].z=target[0][1].z=slope[0];
+	for(int i=0,c=vl.size();i<c;i++)
+		vl[i][0].z=vl[i][1].z=slope[i+1];
+#endif
 
-     std::string Error;
-     YADB::CDBResultSet DBRes;
-     sDBConnPool.Query(sql.c_str(),DBRes,Error);
-     int nCount = DBRes.GetRecordCount( Error );
-     if (nCount < 1)
-     {
-         log_error("修改path失败,数据库中找不到(dat_reader_path_tof_n): 分站id=%d", id);
-         return ;
-     }
+	for(;;)
+	{
+		auto it=find_line(target.back().v[1],0,vl);
+		if(it==vl.end())
+			break;
 
-    log_info( "read_ant_path. The record count=%ld\n", nCount );
-     while ( DBRes.GetNextRecod(Error) )
-     {
-         int reader_id  = 0;
-         DBRes.GetField( "reader_id",reader_id, Error );
+		target.insert(target.end(),it,it+1);
+		vl.erase(it);
+	}
 
-         auto site_ptr=sit_list::instance()->get(reader_id);
-         if(nullptr==site_ptr)
-             continue;
+	for(;;)
+	{
+		auto it=find_line(target.front().v[0],1,vl);
+		if(it==vl.end())
+			break;
 
-         int pid=0;
-         DBRes.GetField( "tof_flag",pid, Error );
+		target.insert(target.begin(),it,it+1);
+		vl.erase(it);
+	}
 
-         double b_x= 0;
-         DBRes.GetField( "b_x",b_x, Error );
+	log_info("初始化分站路径:site_id=%d",m_id);
 
-         double b_y= 0;
-         DBRes.GetField( "b_y",b_y, Error );
+	for(auto&a:m_ant)
+	{
+		a.set_path(target);
+	}
+	m_path_empty= !m_ant[0][0].valid() && !m_ant[0][1].valid() ;
+}
 
-         double b_z= 0;
-         DBRes.GetField( "b_z",b_z, Error );
+std::vector<point> ant::getsol(const double &dist) const
+{
+	std::vector<point> v;
+	for(const auto & p : m_path)
+	{
+		if(!p.valid())
+			continue;
+
+		point pt;
+		double d  = dist;
+
+		if(dist <= p.m_line[0].length())
+		{
+			d += d*p.m_line[0][0].z;
+			pt = point(p.m_line[0][0].x + d*p.m_line[0].cos() , p.m_line[0][0].y + d*p.m_line[0].sin());
+		}
+		else if(p.m_line[1].length()>0)
+		{
+			d -= p.m_line[0].length()*(1-d*p.m_line[0][1].z);
+			d += d*p.m_line[1][0].z;
+
+			pt = point(p.m_line[1][0].x+d*p.m_line[1].cos(),p.m_line[1][0].y+d*p.m_line[1].sin());
+		}
+		else
+		{
+			continue;
+		}
+		v.push_back(pt);
+	}
+	return std::move(v);
+}
 
-         double e_x= 0;
-         DBRes.GetField( "e_x",e_x, Error );
+bool visit_site_status::visit(std::shared_ptr<site> s)
+{
+	time_t now=time(0);
+	int diff = now-s->m_time;
+	event_tool::instance()->handle_event(OT_DEVICE_READER,ET_READER_ERROR,s->m_id,READER_TIMEOUT,diff,[diff](){return diff>READER_TIMEOUT;});
+	return true;
+}
 
-         double e_y= 0;
-         DBRes.GetField( "e_y",e_y, Error );
+void sit_list::read_ant_path(int id)
+{
+	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";
 
-         double e_z= 0;
-         DBRes.GetField( "e_z",e_z, Error );
+	std::map<int,std::vector<line_v>> map_path;
 
-         double spacing_ratio = 0;
-         DBRes.GetField( "spacing_ratio",spacing_ratio, Error );
-         log_info("ant_path:%d,%.2f,%.2f,%.2f,%.2f",reader_id,b_x,b_y,e_x,e_y);
-         point p1(b_x,-b_y);
-         point p2(e_x,-e_y);
-         auto &sit_ = *site_ptr;
-         if(-1!=id)//清空path
-         {
-            sit_.clear_path();
-            log_info( "修改path 清空path,分站id=%d\n", id );
-         }
+	if(-1 == id)
+	{
+		sql.append(";");
+	}
+	else
+	{
+		sql.append(" where reader_id=");
+		sql.append(std::to_string(id));
+		sql.append(";");
+
+		std_debug("修改path sql=%s", sql.c_str());
+		log_info("修改path sql=%s", sql.c_str());
+	}
+
+	std::string Error;
+	YADB::CDBResultSet DBRes;
+	sDBConnPool.Query(sql.c_str(),DBRes,Error);
+	int nCount = DBRes.GetRecordCount( Error );
+	if (nCount < 1)
+	{
+		log_error("修改path失败,数据库中找不到(dat_reader_path_tof_n): 分站id=%d", id);
+		return ;
+	}
 
-         if(pid == 0)
-         {
-             line_v l(p1,p2);
-             {
-                 point px = l.line::projection(sit_);
-                 sit_.set(px);
-                 for(int i=0;i<2;i++)
-                 {
-                     path p;
-                     p.m_slope[0] = spacing_ratio;
-                     p.m_line[0] = line_v(px,l[i]);
-                     sit_.m_ant[i].m_path.push_back(p);
-                 }
-             }
-         }
-         else
-         {
-             ant &a = pid<0?sit_.m_ant[0]:sit_.m_ant[1];
-             if(a.m_path.size()!=0)
-             {
-                 path &p = a.m_path[0];
-                 p.m_line[abs(pid)-1] = line_v(p1,p2);
-                 p.m_slope[abs(pid)-1] = spacing_ratio;
-             }
-             else
-             {
-                 path p;
-                 p.m_line[abs(pid)-1] = line_v(p1,p2);
-                 p.m_slope[abs(pid)-1] = spacing_ratio;
-                 a.m_path.push_back(p);
-             }
-             if(abs(pid)==1)
-                 sit_.set(p1);
-         }
-     }
+	log_info( "read_ant_path. The record count=%ld\n", nCount );
+	while ( DBRes.GetNextRecod(Error) )
+	{
+		int reader_id  = 0;
+		DBRes.GetField( "reader_id",reader_id, Error );
+
+		auto site_ptr=sit_list::instance()->get(reader_id);
+		if(nullptr==site_ptr)
+			continue;
+
+		int pid=0;
+		DBRes.GetField( "tof_flag",pid, Error );
+
+		double b_x= 0;
+		DBRes.GetField( "b_x",b_x, Error );
+
+		double b_y= 0;
+		DBRes.GetField( "b_y",b_y, Error );
+
+		double b_z= 0;
+		DBRes.GetField( "b_z",b_z, Error );
+
+		double e_x= 0;
+		DBRes.GetField( "e_x",e_x, Error );
+
+		double e_y= 0;
+		DBRes.GetField( "e_y",e_y, Error );
+
+		double e_z= 0;
+		DBRes.GetField( "e_z",e_z, Error );
+
+		double spacing_ratio = 0;
+		DBRes.GetField( "spacing_ratio",spacing_ratio, Error );
+		log_info("ant_path:%d,%.2f,%.2f,%.2f,%.2f",reader_id,b_x,b_y,e_x,e_y);
+		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));
+#if 0
+
+		auto &sit_ = *site_ptr;
+		if(-1!=id)//清空path
+		{
+			sit_.clear_path();
+			log_info( "修改path 清空path,分站id=%d\n", id );
+		}
+
+		if(pid == 0)
+		{
+			line_v l(p1,p2);
+			{
+				point px = l.line::projection(sit_);
+				sit_.set(px);
+				for(int i=0;i<2;i++)
+				{
+					path p;
+					p.m_slope[0] = spacing_ratio;
+					p.m_line[0] = line_v(px,l[i]);
+					sit_.m_ant[i].m_path.push_back(p);
+				}
+			}
+		}
+		else
+		{
+			ant &a = pid<0?sit_.m_ant[0]:sit_.m_ant[1];
+			if(a.m_path.size()!=0)
+			{
+				path &p = a.m_path[0];
+				p.m_line[abs(pid)-1] = line_v(p1,p2);
+				p.m_slope[abs(pid)-1] = spacing_ratio;
+			}
+			else
+			{
+				path p;
+				p.m_line[abs(pid)-1] = line_v(p1,p2);
+				p.m_slope[abs(pid)-1] = spacing_ratio;
+				a.m_path.push_back(p);
+			}
+			if(abs(pid)==1)
+				sit_.set(p1);
+		}
+#endif
+	}
 
-     if(-1==id)
-     {
-         for(auto&_s:sit_list::instance()->m_map)
-         {
-             _s.second->deal_path();
-         }
-     }
-     else
-     {
-         auto sit_ptr=sit_list::instance()->get(id);
-         if(sit_ptr)
-         {
-             sit_ptr->deal_path();
-             log_info( "修改path成功,分站id=%d\n", id );
-         }
-     }
+#if 0
+	if(-1==id)
+	{
+		for(auto&_s:sit_list::instance()->m_map)
+		{
+			_s.second->deal_path();
+		}
+	}
+	else
+	{
+		auto sit_ptr=sit_list::instance()->get(id);
+		if(sit_ptr)
+		{
+			sit_ptr->deal_path();
+			log_info( "修改path成功,分站id=%d\n", id );
+		}
+	}
+#endif
+
+	for(auto&vl:map_path)
+	{
+		auto sit_ptr=sit_list::instance()->get(vl.first);
+		if(!sit_ptr)
+		{
+			log_error("定义了分站路径,但是没有定义分站:%d",vl.first);
+			continue;
+		}
+
+		sit_ptr->set_path(vl.second);
+	}
 
-	 card_path::init();
+	card_path::init();
 }
 
 void sit_list::init_site(int id)

+ 19 - 78
ant.h

@@ -23,22 +23,20 @@ class area;
 struct path
 {
     std::array<line_v,2>	m_line;
-    std::array<double,2>    m_slope;
     path()
     {
-        for(auto &d:m_slope)
-            d=0;
     }
+
     std::string to_str() const
     {
         std::stringstream ss;
         for(int i=0;i<2;i++)
         {
-            ss<<"line:" <<m_line[i].to_string()<<"slope:"<<m_slope[i]<< " cos:"<<m_line[i].cos()<<" sin:"<<m_line[i].sin()<<" | ";
+            ss<<"line:" <<m_line[i].to_string()<<"slope:"<<m_line[i][0].z<< " cos:"<<m_line[i].cos()<<" sin:"<<m_line[i].sin()<<" | ";
         }
         return ss.str();
     }
-    bool vaild() const
+    bool valid() const
     {
         return !m_line[0].empty();
     }
@@ -50,7 +48,6 @@ struct path
     {
         return m_line[i];
     }
-
 };
 //?
 struct algo_config
@@ -64,49 +61,27 @@ struct algo_config
 //
 struct ant :point
 {
+    std::array<path,2> m_path;
     int m_id;
-    std::vector<path> m_path;
+
     path & operator[](int i)
     {
         return m_path[i];
     }
+
     const path & operator[](int i) const
     {
         return m_path[i];
     }
+
     size_t size() const
     {
         return m_path.size();
     }
-    std::vector<point> getsol(const double &dist) const
-    {
-        std::vector<point> v;
-        for(const auto & p : m_path)
-        {
-            double d  = dist;
-            if(p.vaild())
-            {
-                point pt;
-                if(dist <= p.m_line[0].length() || (dist > p.m_line[0].length() && p.m_line[1].empty()))
-                {
-                    d += d*p.m_slope[0];
-                    pt = point(p.m_line[0][0].x + d*p.m_line[0].cos() , p.m_line[0][0].y + d*p.m_line[0].sin());
-                }
-                else
-                {
-                    d -= p.m_line[0].length();
-                    d += d*p.m_slope[1];
-                    pt = point(p.m_line[1][0].x+d*p.m_line[1].cos(),p.m_line[1][0].y+d*p.m_line[1].sin());
-                }
-                v.push_back(pt);
-                //std_info("get_sol:x:%.2f,y:%.2f",pt.x,pt.y);
-            }
-            //else
-             //   std_error("ant[%d]::getsol empty path..",);
-        }
-        return std::move(v);
-    }
 
+	void set_path(const std::vector<line_v>&v_line);
+	void set_path(const std::vector<line_v>&v_line,std::vector<line_v>::const_iterator it);
+    std::vector<point> getsol(const double &dist) const;
 };
 
 struct site:point,std::enable_shared_from_this<site>
@@ -234,13 +209,7 @@ struct site:point,std::enable_shared_from_this<site>
             m_ant_dist_cnt_new = 0;
         }
     }
-    void swap()
-    {
-        auto v0 =  m_ant[0].m_path;
-        auto v1 =  m_ant[1].m_path;
-        std::copy (std::begin(v0),std::end(v0),std::back_inserter(m_ant[1].m_path));
-        std::copy (std::begin(v1),std::end(v1),std::back_inserter(m_ant[0].m_path));
-    }
+
     double ant_dist()const
     {
         return m_ant[0].dist(m_ant[1]);
@@ -260,10 +229,10 @@ struct site:point,std::enable_shared_from_this<site>
     {
         std::stringstream ss;
         ss<<"site_id:"<<m_id<<"x:"<<x<<" y: "<<y<<" scale:"<<m_scale;
-        for(const auto a:m_ant)
+        for(const auto&a:m_ant)
         {
             ss<<"<";
-            for(const auto p:a.m_path)
+            for(const auto&p:a.m_path)
             {
                 ss<<"{"<<p.to_str()<<"}";
             }
@@ -280,6 +249,7 @@ struct site:point,std::enable_shared_from_this<site>
         return m_ant[0].m_path[i].m_line[0][1];
     }
 
+	void set_path(const std::vector<line_v>&v_line);
     std::vector<point> solving(int ant_id, double dist)const
     {
         const ant &a = m_ant[ant_id];
@@ -297,11 +267,13 @@ struct site:point,std::enable_shared_from_this<site>
         }
         return std::move(a.getsol(dist));
     }
-    ant operator[](int i)
+
+    ant&operator[](int i)
     {
         return m_ant[i];
     }
-    const ant operator[](int i) const
+
+    const ant&operator[](int i) const
     {
         return m_ant[i];
     }
@@ -321,42 +293,11 @@ struct site:point,std::enable_shared_from_this<site>
         set( (m_ant[0].x+m_ant[1].x)/2,(m_ant[0].y+m_ant[1].y)/2);
     }
 
-    void deal_path()
-    {
-        if(m_id==-1)
-            return;
-        swap();
-        if((path(0).empty() && path(1).empty()))
-            return;
-        m_path_empty=false;
-
-        for(auto &a:m_ant)
-        for(auto &p:a.m_path)
-        {
-            if(!p.m_line[0].empty())
-            {
-                point px = p.m_line[0].line::projection(a);
-                p.m_line[0]=line_v(px,p.m_line[0][1]);
-            }
-        }
-        //std_info("%s",sit_ptr->to_string().c_str());
-        log_info("%s",to_string().c_str());
-        //std_info("%f----%f",sit_ptr->x,sit_ptr->y);
-    }
-
     void delete_antenna(int antidx)
     {
-        m_ant[antidx].m_path.clear();
-        m_ant[antidx].m_id=0;
-        point pt;
-        m_ant[antidx].set(pt);
+        m_ant[antidx].set(point(0,0));
     }
 
-    void clear_path()
-    {
-        m_ant[0].m_path.clear();
-        m_ant[1].m_path.clear();
-    }
 /*
 
 	处理分站供电状态,交流供电时,ac_down=false,直流供电时,ac_down=true

+ 3 - 2
card.cpp

@@ -353,8 +353,9 @@ void card_list::on_message(zloop<task*> *loop,const message_locinfo&loc,bool is_
 		log_warn("数据库中未定义该卡的信息,card_id=%d, card_type=%d,cardid:%lld",loc.m_card_id,loc.m_card_type,cardid);
 		return;
 	}
-	logn_info(3,"card_message:site=%d,ant=%d,type=%lu,card=%d,ct=%d,tof=%lld,rav=%02X,acc=%02X,rssi=%d,stamp=%llu",
-			loc.m_site_id,loc.m_ant_id,loc.m_card_type,loc.m_card_id,loc.m_card_ct,loc.m_tof,loc.m_rav,loc.m_acc,loc.m_rssi,loc.m_time_stamp);
+	double dist_tof=loc.m_tof*15.65*2.996*1e-4;
+	logn_info(3,"card_message:site=%d,ant=%d,type=%lu,card=%d,ct=%d,tof=%lld(%.2lfm),rav=%02X,acc=%02X,rssi=%d,stamp=%llu",
+			loc.m_site_id,loc.m_ant_id,loc.m_card_type,loc.m_card_id,loc.m_card_ct,loc.m_tof,dist_tof,loc.m_rav,loc.m_acc,loc.m_rssi,loc.m_time_stamp);
 
 	c->on_message(loop,loc,is_history);
 }

+ 24 - 6
line.h

@@ -135,9 +135,17 @@ struct line_v:line//线段
 	{
 		v[0]=p0;
 		v[1]=p1;
-        setpoint();
+        recalc();
 	}
-    void setpoint()
+	void swap_point()
+	{
+		point tmp=v[0];
+		v[0]=v[1];
+		v[1]=tmp;
+		recalc();
+	}
+
+    void recalc()
     {
         double dx = v[1].x - v[0].x;
         double dy = v[1].y - v[0].y;
@@ -146,10 +154,15 @@ struct line_v:line//线段
         double sin = dy/r;
         angle = point(cos,sin);
     }
-    double cos() const
-    {return angle.x;}
-    double sin() const
-    {return angle.y;}
+
+	void set_point(int i,const point&p)
+	{
+		v[i]=p;
+		recalc();
+	}
+
+    double cos() const {return angle.x;}
+    double sin() const {return angle.y;}
 	point&operator[](int i) { return v[i]; }
 	const point&operator[](int i)const { return v[i]; }
 
@@ -232,6 +245,11 @@ struct line_v:line//线段
 
 		return v.dist(p);
 	}
+
+	const line &as_line()const
+	{
+		return *this;
+	}
 };
 #endif
 

+ 1 - 1
message.h

@@ -32,7 +32,7 @@ struct message_locinfo:task
 	uint8_t  m_acc;
 	uint8_t  m_ant_id;
 	uint16_t m_sync_ct;
-	uint16_t m_rssi;
+	int16_t  m_rssi;
 
 	void zero_this();
     void load(zistream&is,bool tdoa);

+ 1 - 8
module_service/module_meta_date_changed.cpp

@@ -236,14 +236,7 @@ void module_meta_date_changed::deal_call_edit_path(int id, EDIT_TYPE_ID edit_typ
     }
     else if(ET_DELETE == edit_type_id)
     {
-        auto sit_ptr = sit_list::instance()->get(id);
-        if(sit_ptr)
-        {
-            sit_ptr->clear_path();
-        }
-
-        log_info("path删除成功,分站id=%d", id);
-        std_debug("path删除成功,分站id=%d", id);
+        sit_list::instance()->read_ant_path(id);
     }
 }
 

+ 1 - 4
select_tool.cpp

@@ -198,10 +198,7 @@ bool select_point_object::select_solution(const std::vector<point> &vp,const sit
 	{
 		m_d(0).set_cl(0);
 
-		//printf("out of path:t=%ld,sit=%d,ct=%d,"
-		//"tof1=%d,tof2=%d,pt=(%f,%f)\n",
-		//m_d(0).m_time, m_d(0).m_sid,m_d(0).m_ct,
-		//m_d(0).m_tof[0], m_d(0).m_tof[1], pt.x, pt.y);
+		log_info("out of path:t=%ld,sit=%d,card_id=%d,ct=%d,tof1=%d,tof2=%d,pt=(%f,%f)\n", m_d(0).m_time, m_d(0).m_sid,m_d(0).m_cid,m_d(0).m_ct, m_d(0).m_tof[0], m_d(0).m_tof[1], pt.x, pt.y);
 		return false;
 	}
 

+ 158 - 290
test.cpp

@@ -1,366 +1,234 @@
 #include <unistd.h>
 #include <limits.h>
 #include <stdlib.h>
-#include <stdint.h>
 
-#include <clock.h>
-#include <zio.h>
-#include <log.h>
-#include <zloop.h>
+#include <stdint.h>
 
-#include "base64.h"
-#include "io_buf.h"
+#include <sstream>
+#include <vector>
+#include <line.h>
 
-struct web_client_http:ev::io
+#define log_error printf
+#define log_info printf
+struct path
 {
-	in_buff m_buff;
-	int m_data_len=-1;
-	int m_mask_pos=-1;
-	int m_data_pos=-1;
-	int m_fd,m_status;
-
-	web_client_http()
-		:m_buff(8192)
-	{
-		m_fd=-1;
-	}
-
-	int connect_tcp(const char*ip,int port)
-	{
-		int fd=zio::build_stream();
-		if(zio::connect(fd,ip,port))
-		{
-			zio::close(fd);
-			return m_fd=-1;
-		}
-
-		zio::setiobuf(fd,16<<10,16<<10);
-		zio::setblocking(fd,false);
-
-		return m_fd=fd;
-	}
+    std::array<line_v,2>	m_line;
+    path()
+    {
+    }
+
+    std::string to_str() const
+    {
+        std::stringstream ss;
+        for(int i=0;i<2;i++)
+        {
+            ss<<"line:" <<m_line[i].to_string()<<"slope:"<<m_line[i][0].z<< " cos:"<<m_line[i].cos()<<" sin:"<<m_line[i].sin()<<" | ";
+        }
+        return ss.str();
+    }
+    bool vaild() const
+    {
+        return !m_line[0].empty();
+    }
+    line_v & operator[](int i)
+    {
+        return m_line[i];
+    }
+    const line_v & operator[](int i) const
+    {
+        return m_line[i];
+    }
+};
 
-	void ws_reset()
-	{
-		if(m_data_pos+m_data_len>0)
-		{
-			m_buff.free(m_data_len+m_data_pos);
-		}
+struct tant:point
+{
+int m_id;
 
-		m_data_len=-1;
-		m_mask_pos=-1;
-		m_data_pos=-1;
-	}
+void set_path(const std::vector<line_v>&v_line,std::vector<line_v>::const_iterator itm)
+{
+	std::array<path,2> m_path;
 
-	bool ws_fin()const
-	{
-		return (m_buff[0]&0x80) != 0;
-	}
+	auto 
 
-	bool ws_more()const
-	{
-		return (m_buff[0]&0xF) ==0 ;
-	}
+	it=itm;
+	for(int i=0;i<2 && it!=v_line.end();++it,++i)
+		m_path[0][i]=*it;
 
-	bool ws_text()const
+	it=itm-1;
+	for(int i=0;i<2 && it>=v_line.begin();--it,++i)
 	{
-		return (m_buff[0]&0xF) ==1 ;
+		m_path[1][i]=*it;
+		m_path[1][i].swap_point();
 	}
 
-	bool ws_bin()const
+	for(auto&p:m_path)
 	{
-		return (m_buff[0]&0xF) ==2 ;
+		log_info("%s\n",p.to_str().c_str());
 	}
+}
 
-	bool ws_ping()const
+void set_path2(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++)
 	{
-		return (m_buff[0]&0xF) ==9 ;
+		double d=it->as_line().dist(*this);
+		if(d<dist)
+		{
+			dist=d;
+			min_it=it;
+		}
 	}
 
-	bool ws_pong()const
+	if(min_it==vl.end())
 	{
-		return (m_buff[0]&0xF) ==10 ;
+		log_error("分站路径距离分站太远site_id=%d",m_id);
+		return;
 	}
 
-	bool ws_close()const
+	if(abs(min_it->v[0].dist(*this)-dist)<1)
 	{
-		return (m_buff[0]&0xF) ==8 ;
+		set_path(vl,min_it);
 	}
-
-	bool ws_mask()const
+	else if(abs(min_it->v[1].dist(*this)-dist)<1)
 	{
-		return (m_buff[1]&0x80) !=0 ;
+		set_path(vl,min_it+1);
 	}
-
-	int parse_length()
+	else
 	{
-		if(m_buff.len_data()<2)
-			return -1;
-
-		if(m_data_pos>0)
-			return 0;
-
-		if((m_buff[1]&0x7F)<=125)
-		{
-			m_mask_pos=ws_mask()?2:-1;
-			m_data_pos=ws_mask()?6:2;
+		point proj=min_it->projection(*this);
+		vl.insert(min_it+1,line_v(proj,min_it->v[1]));
+		min_it->set_point(1,proj);
 
-			m_data_len=m_buff[1]&0x7F;
-		}
-		else
-		if((m_buff[1]&0x7F)==126)
+		if(min_it->v[0].z)//slope ..555
 		{
-			if(m_buff.len_data()<4)
-				return -1;
-
-			m_mask_pos=ws_mask()?4:-1;
-			m_data_pos=ws_mask()?8:4;
-
-			m_data_len=(m_buff[2]<<8) | m_buff[3];
+			double slope=min_it->v[0].z;
+			double len_a=min_it->v[0].dist((min_it+1)->v[1]);
+			double len_0=slope*min_it->length()/len_a;
+			double len_1=slope-len_0;
+			
+			min_it->v[0].z=min_it->v[1].z=len_0;
+			(min_it+1)->v[0].z=(min_it+1)->v[1].z=len_1;
 		}
-		else
-		{
-			if(m_buff.len_data()<9)
-				return -1;
-
-			m_mask_pos=ws_mask()?9:-1;
-			m_data_pos=ws_mask()?13:9;
 
-			//不考虑大于20G的数据
-			m_data_len=(m_buff[6]<<24)|(m_buff[7]<<16)|(m_buff[8]<<8)|(m_buff[9]);
-		}
-		
-		int i=0;
-		for(i=0;i<m_data_len;i++)
-		{
-			uint8_t b=m_buff[m_data_pos+i];
-			if(b>=0x30 && b<=0x39)
-				continue;
-			break;
-		}
-
-		m_data_len-=i;
-		m_data_pos+=i;
-
-		return 0;
+		set_path(vl,min_it+1);
 	}
+}
+};
 
-	void mask(const uint8_t*m,uint8_t*d,int len)
+void print_vl(const std::vector<line_v>&vl)
+{
+	printf("-----------------------------------\n");
+	for(auto&v:vl)
 	{
-		for(int i=0;i<len;i++)
-			d[i]=d[i]^m[i&3];
+		printf("%s\n",v.to_string().c_str());
 	}
 
-	int ws_parse()
-	{
-		if(parse_length()<0)
-			return -1;
-
-		if(m_buff.len_data()<m_data_pos+m_data_len)
-			return -1;
+}
 
-		if(ws_mask())
-		{
-			mask(&m_buff[m_mask_pos],&m_buff[m_data_pos],m_data_len);
-		}
+void set_path(const std::vector<line_v>&v_line,const std::vector<double>&slope)
+{
+	if(v_line.empty())
+		return;
 
-		for(int i=0;i<m_data_len;i++)
+	const auto&find_line=[](const point&pt,int first,std::vector<line_v>&vl){
+		for(auto it=vl.begin();it!=vl.end();it++)
 		{
-			printf("%c",m_buff[m_data_pos+i]);
+			if(it->v[first].dist(pt)<1)
+				return it;
+			if(it->v[first?0:1].dist(pt)<1)
+			{
+				point p=it->v[0];
+				it->v[0]=it->v[1];
+				it->v[1]=p;
+				return it;
+			}
 		}
 
-		printf("\n\n");
+		return vl.end();
+	};
+	
+	//构造一个首尾相连的结构
 
-		return 0;
-	}
+	print_vl(v_line);
+	std::vector<line_v> vl(v_line.begin()+1,v_line.end());
+	std::vector<line_v> target(v_line.begin(),v_line.begin()+1);
 
+	target[0][0].z=target[0][1].z=slope[0];
+	for(int i=0,c=vl.size();i<c;i++)
+		vl[i][0].z=vl[i][1].z=slope[i+1];
 
-	int connect_ws(const char*ip,int port)
+	for(;;)
 	{
-		unsigned char k[16], k6[128];
-
-		for(size_t i=0;i<sizeof(k);i++)
-			k[i]=rand();
-
-		base64::encode(k,sizeof(k),k6);
-
-		const char*fmt=
-			"GET /socket.io/?EIO=3&transport=websocket HTTP/1.1\r\n"
-			"Host: %s:%d\r\n"
-			"Connection: Upgrade\r\n"
-			"Pragma: no-cache\r\n"
-			"Cache-Control: no-cache\r\n"
-			"Upgrade: websocket\r\n"
-			"Origin: http://%s:%d\r\n"
-			"Sec-WebSocket-Version: 13\r\n"
-			"Accept-Encoding: gzip, deflate\r\n"
-			"Accept-Language: zh-CN,zh;q=0.9\r\n"
-			"Sec-WebSocket-Key: %s\r\n"
-			"Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits\r\n\r\n";
-
-		if(connect_tcp(ip,port)<0)	
-			return -1;
-
-		char buf[512];
-		int len=sprintf(buf,fmt,ip,port,ip,port,k6);
-
-		if(len!=zio::writev(m_fd, buf, len))
-		{
-			close();
-			return -1;
-		}
-
-		sleep(1);
-		if(read_until("\r\n\r\n")<=0)
-		{
-			close();
-			return -1;
-		}
-
-		if(m_buff.find("101 Switching Protocols\r\n"))
-		{
-			m_buff.skip(m_buff.find("\r\n\r\n"));
-			return 0;
-		}
+		auto it=find_line(target.back().v[1],0,vl);
+		if(it==vl.end())
+			break;
 
-		close();
-		return -1;
+		target.insert(target.end(),it,it+1);
+		vl.erase(it);
 	}
 
-	int request(const char*what)
+	for(;;)
 	{
-		int len=strlen(what);
-
-        if(len!=zio::writev(m_fd, what, len))
-		{
-			close();
-			return -1;
-		}
+		auto it=find_line(target.front().v[0],1,vl);
+		if(it==vl.end())
+			break;
 
-		return 0;
+		target.insert(target.begin(),it,it+1);
+		vl.erase(it);
 	}
 
-	int read_until(const char*what,int timeout=10*1000)
-	{
-		int rc=0;
-		zclock c;
-		for(;;)
-		{
-			buff_t b=m_buff.alloc();
-			if(b.empty())
-			{
-				m_buff.grow(1024);
-				b=m_buff.alloc();
-			}
-
-			int len=zio::read(m_fd,b.ptr(),b.len());
-
-			if((int)c.count_ms()>timeout)
-			{
-				log_error("websocket read timeout in %dms",timeout);
-				return -1;
-			}
-
-			if(len==-1)
-			{
-				return -1;
-			}
+	print_vl(target);
 
-			if(len==-2)
-				continue;
+	tant ta;
 
-			if(len==0)
-			{
-				log_info("remote close the socket");
-				return 0;
-			}
+	ta.set(100,100);
+	ta.set_path2(target);
+}
 
-			m_buff.commit(len);
-			rc+=len;
 
-			if(m_buff.find(what))
-				return rc;
-		}
-	}
 
+int main()
+{
+{
+	std::vector<line_v> vl;
 
-	void close()
-	{
-		zio::close(m_fd);
-	}
-
-	~web_client_http()
-	{
-		close();
-	}
-};
+	vl.push_back(line_v(point(-10,0),point(0,0)));
+	vl.push_back(line_v(point(0,0),point(100,100.1)));
 
-int realpath_test()
+	print_vl(vl);
+	set_path(vl,{10,20});
+}
 {
-	char buf[4096];
+	std::vector<line_v> vl;
 
-	realpath(".",buf);
-	log_info("curpath=%s",buf);
+	vl.push_back(line_v(point(200,200),point(100,100.1)));
+	vl.push_back(line_v(point(200,200),point(200,220)));
 
-	return 0;
-}
 
-#if 0
-std::string test_json()
+	set_path(vl,{10,20});
+}
 {
-	struct json
-	{
-		json&put(const char*k,const json&n)
-		{
-		
-			return *this;
-		}
-	
-		json&put(const char*k,int v)
-		{
-		
-			return *this;
-		}
-		json&put(const char*k,const char*v)
-		{
-		
-			return *this;
-		}
+	std::vector<line_v> vl;
 
-		std::string to_string()const
-		{
-			return std::string();
-		}
-	};
+	vl.push_back(line_v(point(-10,0),point(0,0)));
+	vl.push_back(line_v(point(0,0),point(200,200)));
 
-	return json().put("cmd","login")
-				 .put("data",json()
-				 	 .put("uname","wyj")
-					 .put("passwd",111111)
-				  ).to_string();
-}
-#endif
 
-int main()
+	set_path(vl,{10,20});
+}
 {
-	unsigned char buf[32];
-	const char*s64="puVOuWb7rel6z2AVZBKnfw==";
-	const char*login="{\"cmd\":\"login\",\"data\":{\"user_name\":\"zzj\",\"user_pass\":\"111111\"}}\n";
+	std::vector<line_v> vl;
 
-	int blen=32;
-	base64::decode((char*)s64,strlen(s64),buf,blen);
+	vl.push_back(line_v(point(0,0),point(200,200)));
 
-	web_client_http client;
-	client.connect_ws("127.0.0.1",9001);
 
-	for(;;)
-	{
-		while(client.ws_parse()==0)
-			client.ws_reset();
-
-		client.request(login);
-		client.read_until("\n");
-	}
+	set_path(vl,{10});
+}
 
 	return 0;
 }

+ 2 - 2
znet.cpp

@@ -55,7 +55,7 @@ public:
 
 	void boardcast(const std::vector<char>&msg)
 	{
-		for(auto i:m_thread_clts)
+		for(auto&i:m_thread_clts)
 		{
 			std::vector<char> tmp(msg);
 			i->send(std::move(tmp));
@@ -99,7 +99,7 @@ public:
 
 	void close_all()
 	{
-		for(auto clt:m_thread_clts)
+		for(auto&clt:m_thread_clts)
 		{
 			if(!clt)
 				continue;