1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060 |
- #include "stdafx.h"
- #include "trafficLight.h"
- #include "carManager.h"
- #include "ProcessRemodule.h"
- // #include "INIFILE.h"
- // #include "def.h"
- //路口红绿灯
- //大巷红绿灯
- NAMESPACE_POINT_BEGIN(NAMESPACE_POINT)
- //路口规则
- //小车避让大车规则
- //代理模式
- //装饰器模式
- //抽象工厂模式
- //x->大 speed 正
- //x->恒
- // y->大 speed 正
- // y->小 speed 负
- //x->小 speed 负
- //这里的初始化红绿灯组vector初始化,因数据库配置和实际情况进行初始化,不能保证通用,需要在不同的情形下特殊处理
- //这里是根据区域划分红绿灯,然后根据红绿灯位置按照(上行或者下行)进行排序
- //这里初始化根据,每一条巷道为一组,遇到拐点,则是新的巷道。因为,拐点必有红绿灯。
- //需要考虑到T字口和十字口中有车辆过来,但非是指定区域即辅运大巷
- std::vector<std::string> Rule::find_near(int x,int y,int dist,const std::string & card_no)
- {
- std::vector<std::string> v;
- if(auto pt = m_owner.lock())
- v = pt->find_near(x,y,dist,card_no);
- return std::move(v);
- }
- std::shared_ptr<card_interface> Rule::getCard(const std::string &card_no)
- {
- //return m_[card_no];
- std::shared_ptr<card_interface> c = nullptr;
- if(auto pt = m_owner.lock())
- c = pt->getCard(card_no);
- return c;
- }
- //谁先到达路口红绿灯指定的距离,which side turn green.then else turn red..
- //
- bool CrossingRule::getBigCarFlag(const std::string &card_no)
- {
- bool flag=false;
- auto cardPtr = getCard(card_no);
- if(cardPtr!=nullptr)
- flag = cardPtr->getBigCarFlag();
- return flag?false:true;
- }
- //here should another thread to handle it .
- bool CrossingRule::handleManualControl(std::shared_ptr<TrafficLightGroup> pt)
- {
- if(pt->timeout())
- {
- pt->resetGroup();
- return true;
- }
- return false;
- }
- bool CrossingRule::findNearLight(const std::string & card_no,std::shared_ptr<TrafficLightGroup> tlg_ptr,bool a )
- {
- bool flag = false;
- auto cardPtr = getCard(card_no);
- double distance = 0.0;
- if(cardPtr!=nullptr)
- {
- bool special = false;
- line l;
- double distDirect = 0;
- double x=cardPtr->getX();
- double y=cardPtr->getY();
- double v=cardPtr->getv();
- auto lightinfo = findNearLightInfo(x,y,tlg_ptr);
- special = std::get<0>(lightinfo);
- l = std::get<1>(lightinfo);
- distDirect = std::get<2>(lightinfo);
- distance = l.dist(op::point(x,y));
- //debug_print_syslog(0,"findNearLight.x:%0.3f,y:%0.3f,v:%0.3f,dist:%0.3f,",x,y,v,distDirect);
- if (!a)
- {
- if(special)
- {
- //判断是否在线上
- if(l.contain(x,y,0.5))
- {
- //判断行车方向
- double c = v*distDirect;
- if(c<0)
- flag = true;
- }
- }
- }
- else
- {
- if((tlg_ptr->m_gId == 2 || tlg_ptr->m_gId == 4)||tlg_ptr->m_gId == 11)
- {
- flag = true;
- }else if(tlg_ptr->m_gId == 8 ||tlg_ptr->m_gId == 18||tlg_ptr->m_gId == 20)
- {
- flag = true;
- }
- else if(l.contain(x,y,1.0))
- {
- double c = v*distDirect;
- if(c<0)
- flag = true;
- }else{
- debug_print_syslog(0,"lamp light: findNearLight: gid: %d,card_id: %s, distance: %.3f",tlg_ptr->m_gId,card_no.c_str(),l.dist(op::point(x,y)));
- }
-
- //判断是否在线上
- //if(l.contain(x,y,1.0))
- //{
- // double c = v*distDirect;
- // //debug_print_syslog(0,"findNearLight:%0.3f,%s",c,c<0?"TRUE":"FALSE");
- // if(c<0)
- // flag = true;
- //}
- }
- debug_print_syslog(0,"lamp light :findNearLight flag: %s gid: %d,card_id: %s,distance: %.3f,a: %d, special: %d",flag?"TRUE":"FALSE",tlg_ptr->m_gId,card_no.c_str(),distance,a,special);
- }else{
- debug_print_syslog(0,"lamp light :findNearLight gid: %d,card_id: %s ",tlg_ptr->m_gId,card_no.c_str());
- }
-
- return flag?false:true;
- }
- bool CrossingRule::handleSpecialAvondance(std::shared_ptr<TrafficLightGroup> pt)
- {
- //查看是否是大车
- //true标识特殊红绿灯,需要检测大车避让规则
- bool flag = false;
- do{
- auto vt = find_near(static_cast<int>(pt->x),static_cast<int>(pt->y),(int)(ConfStruct::getCs().max_scope_bigCar),itostr(pt->m_gId));
- //筛选大车
- if(vt.empty()) {
- flag = true;break;
- }
- vt.erase(std::remove_if(vt.begin(),vt.end(),[&](const std::string &card_no){
- return getBigCarFlag(card_no);
- }),vt.end());
- if(vt.empty()) {
- flag = true;
- break;
- }
- vt.erase(std::remove_if(vt.begin(),vt.end(),[](const std::string &name){
- if(0 == name.compare(0,3,"002"))
- return false;
- else
- return true;}),vt.end());
- if(vt.empty()) {
- flag = true;
- break;
- }
- //查看离最近的点是否为特殊点,判断位置是否在直线上,判断方向
- vt.erase(std::remove_if(vt.begin(),vt.end(),[&](const std::string &card_no){
- return findNearLight(card_no,pt);
- }),vt.end());
- if(vt.empty()) {
- flag = true;
- break;
- }
- //特殊规则保留id且优先级2,避让规则置空id,优先级2
- if(pt->noCar())
- {
- if(pt->load()== PRI_AVOIDANCE)
- break;
- }
- else
- {
- if(pt->load()== PRI_AVOIDANCE)
- {
- auto it = std::find(vt.begin(),vt.end(),pt->getId());
- if(it != vt.end())
- break;
- }
- }
- //排序,找到离之最近的大车
- std::sort(vt.begin(),vt.end(),[&](const std::string &card_no,const std::string & card){return sortCar(card_no,card,pt);});
- changeCarState(vt[0],pt);
- pt->setCrossing(vt[0],PRI_AVOIDANCE);
- //here return directly
- return true;
- }while(false);
- if(flag)
- {
- //找不到之前的车辆。则初始化
- if(pt->load() == PRI_AVOIDANCE && !pt->noCar())
- pt->resetGroup();
- else
- flag = false;
- }
- return flag;
- }
- bool CrossingRule::handleCrossing(std::shared_ptr<TrafficLightGroup> pt)
- {
- bool flag = false;
- int exit_flag = -1;
- //查找一定范围的车辆
- do{
- auto vt = find_near(static_cast<int>(pt->x),static_cast<int>(pt->y),pt->scope(),itostr(pt->m_gId));
- if(!vt.empty())
- {
- //std::cout <<""<<std::endl;
- debug_print_syslog(0,"lamp light: CrossingRule::handleCrossing gid: %d,scope: %.3f",pt->m_gId,pt->m_scope);
- }
- vt.erase(std::remove_if(vt.begin(),vt.end(),[&](const std::string &name)->bool{
- bool a = false;
- debug_print_syslog(0,"lamp light: CrossingRule::handleCrossing card_id: %s, gid: %d,line: %d",name.c_str(),pt->m_gId,__LINE__);
- if(0 == name.compare(0,3,"002"))
- a = findNearLight(name,pt,true);
- else
- a = true;
- return a;
- }),vt.end());
- //如果为空表示没找到车
- if(vt.empty())
- {
- if(!pt->noCar()&& pt->load() == PRI_CROSSING)
- {
- //释放红绿灯组
- pt->resetGroup();
- flag = true;
- }
- exit_flag = 1;
- break;
- }
- //是否已经有车记录
- if(!pt->noCar())
- {
- auto it = std::find(vt.begin(),vt.end(),pt->getId());
- if(it!=vt.end()){
- exit_flag = 2;
- break;
- }
- }
- std::sort(vt.begin(),vt.end(),[&](const std::string &card_no,const std::string & card){
- return sortCar(card_no,card,pt);
- });
- //设置优先级以及卡id
- pt->setCrossing(vt[0],PRI_CROSSING);
- //修改红绿灯组状态
- changeCarState(vt[0],pt);
- flag = true;
- }while(false);
- if (exit_flag!=-1)
- {
- debug_print_syslog(0,"lamp light: gid: %d, exit_flag : %d",pt->m_gId,exit_flag);
- }
- return flag;
- }
- std::vector<std::shared_ptr<TrafficLightGroup>> CrossingRule::handleRule(std::shared_ptr<card_interface> c/*=nullptr*/)
- {
- debug_print_syslog(0,"lamp light:CrossingRule::handleRule size: %d, line: %d",m_CTrafficLightGroupMap.size(),__LINE__);
- std::vector<std::shared_ptr<TrafficLightGroup>> plist;
- for(auto &pt : m_CTrafficLightGroupMap)
- {
- pt->getTurn();//获取控制权
- int priority = pt->load();
- //debug_print_syslog(0,"lamp light: priority: %d",priority);
-
- bool flag = false;
- do{
- if(priority == PRI_MANUALCONTROL)
- {
- flag = handleManualControl(pt) ;
- if(flag)
- break;
- }
- if(pt->load() <= PRI_AVOIDANCE && pt->getflag())
- {
- flag = handleSpecialAvondance(pt);
- if(flag)
- break;
- }
- if(pt->load()<=PRI_CROSSING)
- {
- flag = handleCrossing(pt);
- if(flag)
- {
- break;
- }
- }
- }while(false);
- pt->releaseTurn();//释放控制权。
- if(flag)
- {
- plist.push_back(pt);
- }
- }
- //for(const auto & g : plist)
- // std::cout <<"CCCCCCCCCCCCCCCCCCCCCCCC"<< g->showinfo()<<std::endl;
- return std::move(plist);
- }
-
- void CrossingRule::changeCarState(std::string & card_no,std::shared_ptr<TrafficLightGroup> tlg_ptr)
- {
- int lightId = 0;
- auto cardPtr = getCard(card_no);
- if(cardPtr!=nullptr)
- {
- double x=cardPtr->getX();
- double y=cardPtr->getY();
- auto lightinfo = findNearLightInfo(x,y,tlg_ptr);
- std::time_t t = time(NULL);
- if(t-cardPtr->get_last_recv_time()>= 10)
- {
- return;
- }
- lightId = std::get<3>(lightinfo);
- if(tlg_ptr->m_sCardId.empty())
- {
- tlg_ptr->m_sCardId = card_no;
- }
- debug_print_syslog(0,"lamp light: changeCarState card: %s, light id: %d",card_no.c_str(),lightId);
- tlg_ptr->setLight(lightId,GREEN,RED);
- /*double x=cardPtr->getX();
- double y=cardPtr->getY();
- auto lightinfo = findNearLightInfo(x,y,tlg_ptr);
- lightId = std::get<3>(lightinfo);
- debug_print_syslog(0,"red green: changeCarState card: %s, light id: %d",card_no.c_str(),lightId);
- tlg_ptr->setLight(lightId,GREEN,RED);*/
- }
- }
- std::vector<std::shared_ptr<TrafficLightGroup>> AvoidanceRule::handleRule(std::shared_ptr<card_interface> c/*=nullptr*/)
- {
- debug_print_syslog(0,"lamp light: AvoidanceRule::handleRule size: %d, line: %d",m_CTrafficLightGroupMap.size(),__LINE__);
- int aid = c->getAreaId();
- double x = c->getX();
- double y = c->getY();
- double v = c->getv();
- auto it = m_CTrafficLightGroupMap.find(aid);
- std::vector<std::shared_ptr<TrafficLightGroup>> vt;
- if(it != m_CTrafficLightGroupMap.end())
- {
- //根据车卡的定位坐标以及定位区域信息获取红绿灯组
- auto a = findGroup(x,y,aid,v,c);
- debug_print_syslog(0, "lamp light: card: %s, x:%.4f, y:%.4f, led group size: %d, c size: %d",c->cardId().c_str(),x,y,a.size(),c->size());
- if(a.size()==0) // 所在区域没有可以控制的红绿灯组
- {
- if(c->size()==1) // 当前车辆控制的路口为1个,释放该路口控制
- {
- debug_print_syslog(0, "red green: a is 0, c is 1");
- eraseTrafficLightGroup(true,c,vt);
- }
- else if(c->size()==2) // 当前车辆控制的路口为两个,释放这两个路口的控制
- {
- debug_print_syslog(0, "red green: a is 0, c is 2");
- eraseTwoGroup(c,vt);
- }
- }
- else if(a.size()==1) // 所在区域存在一个红绿灯组
- {
- if(c->size()==0) // 当前卡没有绑定红绿灯组,绑定此灯组,并设置灯组颜色为绿色?
- {
- debug_print_syslog(0, "red green: a is 1, c is 0");
- add_one(a[0],c,vt,GREEN,RED);
- }
- else if(c->size()==1) // 当前卡绑定了一个红绿灯组
- {
- if(c->front() != a[0]) // 当前卡绑定的红绿灯组与a不是同一个,不是,释放之前的绑定,再绑定灯组a
- {
- debug_print_syslog(0, "red green: a is 1, c is 1 c != a");
- eraseTrafficLightGroup(true,c,vt);
- add_one(a[0],c,vt,GREEN,RED);
- }
- else // 当前卡绑定的红绿灯组与a是同一个
- {
- debug_print_syslog(0, "red green: a is 1, c is 1 c == a");
- auto i = findNearLightInfo(x,y,a[0]);
- int ld = std::get<3>(i);
- debug_print_syslog(0, "red green: a is 1, c is 1 c == a old id: %d, new id: %d",a[0]->m_nLightId, ld);
- if(ld != a[0]->m_nLightId) // 灯组中离车最近的灯ID已经不是原来绑定路口的灯ID了,说明正在经过路口,需释放控制
- {
- eraseTrafficLightGroup(true,c,vt);
- }
- //if (Diff(a[0],point(x,y),GREEN,RED))
- //vt.push_back(a[0]);
- //else // 车辆位置超过路口灯组位置,释放灯组
- //eraseTrafficLightGroup(true,c,vt);
- }
- }
- else if(c->size()==2) // 当前卡绑定了两个红绿灯组
- {
- auto pt = a[0];
- if(c->front() == pt)
- {
- eraseTrafficLightGroup(false,c,vt);
- if(pt->load()<=2)
- {
- changeGroup(pt,point(x,y),GREEN,RED);
- vt.push_back(pt);
- }
-
- }
- else if(c->back() == pt)
- {
- eraseTrafficLightGroup(true,c,vt);
- if(pt->load()<=2)
- {
- changeGroup(pt,point(x,y),GREEN,RED);
- vt.push_back(pt);
- }
- }
- else
- {
- eraseTwoGroup(c,vt);
- add_one(pt,c,vt,GREEN,RED);
- }
- }
- }
- else if(a.size()==2) // 所在区域存在两个红绿灯组,巷道相遇逻辑
- {
- bool b = getMidCar(c,a[0],a[1]); // 判断两个灯组中是否有车
- LIGHT_COLOUR la,lb;
- if(b)
- {
- la = RED;
- lb = SPARK;
- }
- else
- {
- la = GREEN;
- lb = RED;
- }
- if(c->size()==0)
- {
- add_one(a[0],c,vt,la,lb);
- add_one(a[1],c,vt,GREEN,SPARK);
- }
- else if(c->size()==1)
- {
- if(c->front() == a[0])
- {
- if(a[0]->load()<=2)
- {
- changeGroup(a[0],point(x,y),la,lb);
- vt.push_back(a[0]);
- }
- add_one(a[1],c,vt,GREEN,SPARK);
- }
- else if(c->front() == a[1])
- {
- if(a[1]->load()<=2)
- {
- changeGroup(a[1],point(x,y),GREEN,SPARK);
- vt.push_back(a[1]);
- }
- c->push_front(a[0]);
- if(a[0]->load()<2)
- {
- changeGroup(a[0],point(x,y),la,lb);
- vt.push_back(a[0]);
- }
- }
- else
- {
- eraseTrafficLightGroup(false,c,vt);
- add_one(a[0],c,vt,la,lb);
- add_one(a[1],c,vt,GREEN,SPARK);
- }
- }
- else if(c->size()==2)
- {
- bool b1 = c->find(a[0]);
- bool b2 = c->find(a[1]);
- if(b1)
- {
- if(b2)
- {
- if(c->front() == a[0])
- {
- if (Diff(a[0],point(x,y),la,lb))
- vt.push_back(a[0]);
- if (Diff(a[1],point(x,y),GREEN,SPARK))
- vt.push_back(a[1]);
- }
- else
- {
- c->clear();
- if(a[0]->load()<=2)
- {
- changeGroup(a[0],point(x,y),la,lb);
- vt.push_back(a[0]);
- }
- if(a[1]->load()<=2)
- {
- changeGroup(a[1],point(x,y),GREEN,SPARK);
- vt.push_back(a[1]);
- }
- c->push_back(a[0]);
- c->push_back(a[1]);
- }
- }
- else
- {
- if(c->front() == a[0])
- {
- eraseTrafficLightGroup(false,c,vt);
- add_one(a[1],c,vt,GREEN,SPARK);
- }
- else
- {
- eraseTrafficLightGroup(true,c,vt);
- if(a[0]->load()<=2)
- {
- changeGroup(a[0],point(x,y),la,lb);
- vt.push_back(a[0]);
- }
- add_one(a[1],c,vt,GREEN,SPARK);
- }
- }
- }
- else
- {
- if(b2)
- {
- if(c->front() == a[1])
- {
- eraseTrafficLightGroup(false,c,vt);
- }
- else
- {
- eraseTrafficLightGroup(true,c,vt);
- }
- if(a[1]->load()<=2)
- {
- changeGroup(a[1],point(x,y),GREEN,SPARK);
- vt.push_back(a[1]);
- }
- c->push_front(a[0]);
- if(a[0]->load()<2)
- {
- changeGroup(a[0],point(x,y),la,lb);
- vt.push_back(a[0]);
- }
- }
- else
- {
- eraseTwoGroup(c,vt);
- add_one(a[0],c,vt,la,lb);
- add_one(a[1],c,vt,GREEN,SPARK);
- }
- }
- }
- }
- }
- return std::move(vt);
- }
- std::shared_ptr<RunRedLight> AvoidanceRule::check_run_red_light(std::shared_ptr<card_interface> c,double reddis)
- {
- int aid = c->getAreaId();
- double x = c->getX();
- double y = c->getY();
- double vv = c->getv();
- bool bealarm = false;
- int LightId =0;
- int32_t groupid=0;
- auto it = m_CTrafficLightGroupMap.find(aid);
- if(it != m_CTrafficLightGroupMap.end())
- {
- double d= 0;
- double dis = 0;
- auto v = it->second;
- for(std::size_t i = 0;i<v.size();i++)
- {
- //如果此灯组被控制了,而且不是自己控制
- if ((v[i]->get_status()&&v[i]->m_sCardId != c->cardId())||(!v[i]->noCar()&&v[i]->getId() != c->cardId()))
- {
- LightId =-1;
- if (v[i]->get_status())
- {
- LightId = v[i]->m_nLightId;
- }
- else
- {
- for(auto & px :v[i]->m_pTrafficLight)
- {
- if (px->getState()==GREEN)
- {
- LightId = px->getid();
- }
- }
- }
- if (LightId ==-1)
- {
- continue;
- }
- d = v[i]->dist_direct(x,y); // 求灯组到车辆的距离(车辆在灯组的左下方,则距离值取反)
- std::shared_ptr<TrafficLight> & light = v[i]->get (LightId);
- if (light)
- {
- if(d<=0) // 车辆在灯组左边或下边
- {
- if(vv>0) // 速度方向与前进方向一致
- {
- double dis = light->dist(x,y);
- if (dis < reddis)
- {
- bealarm = true;
- groupid = v[i]->m_gId;
- break;
- }
- }
- }
- else
- {
- if(vv<0)
- {
- dis = light->dist(x,y);
- if (dis < reddis)
- {
- groupid = v[i]->m_gId;
- bealarm = true;
- break;
- }
- }
- }
- }
- }
- }
- if (bealarm)
- {
- //闯红灯
- std::shared_ptr<RunRedLight> redalarm = std::make_shared<RunRedLight>();
- redalarm->m_group_id = groupid;
- redalarm->m_light_id = LightId;
- //车辆id,
- redalarm->m_vehicle_id=0;
- //区域id,
- redalarm->m_area_id=aid;
- //闯红灯时间
- time_t tCurTime;
- tCurTime = time(NULL);
- redalarm->m_time=CFunctions::time_t2string(tCurTime);
- return redalarm;
- }
- }
- return nullptr;
- }
- // 给车卡c绑定路口灯组控制,并更改灯组中灯的颜色状态
- void AvoidanceRule::add_one(std::shared_ptr<TrafficLightGroup> & pt,std::shared_ptr<card_interface> &c,std::vector<std::shared_ptr<TrafficLightGroup>> &vt,LIGHT_COLOUR lc,LIGHT_COLOUR lc_)
- {
- double x = c->getX();
- double y = c->getY();
- c->push_back(pt);
- if(pt->load()<2) // 红绿灯组优先级取初始值0或路口控制1
- {
- changeGroup(pt,point(x,y),lc,lc_);
- vt.push_back(pt);
- }
- auto i = findNearLightInfo(x,y,pt);
- int ld = std::get<3>(i);
- pt->m_nLightId = ld;
- pt->m_sCardId = c->cardId(); // 绑定此灯组的卡号
- debug_print_syslog(0, "lamp light: add_one light group : %d, light id: %d card: %s", pt->m_gId, pt->m_nLightId, pt->m_sCardId.c_str());
- pt->set_status(true);
- }
- bool AvoidanceRule::Diff(std::shared_ptr<TrafficLightGroup> &p,point pt,LIGHT_COLOUR lc,LIGHT_COLOUR lc_)
- {
- bool b =false;
- auto i = findNearLightInfo(pt.x,pt.y,p);
- int ld = std::get<3>(i);
- //if(ld != p->m_nLightId) // 灯组中离车最近的灯ID已经不是原来绑定路口的灯ID了,说明正在经过路口,需释放控制
- //{
- //return false;
- //}
- if (p->Diff(ld,lc,lc_))
- b = true;
- return b;
- }
- // 改变点p定位附近灯组的状态,满足条件的灯状态改为lc,否在为lc_
- void AvoidanceRule::changeGroup(std::shared_ptr<TrafficLightGroup> &p,point pt,LIGHT_COLOUR lc,LIGHT_COLOUR lc_)
- {
- // 1. 在p中取离pt最近的灯组信息
- auto i = findNearLightInfo(pt.x,pt.y,p);
- // 2. 获取灯组中临近车辆的灯ID
- int ld = std::get<3>(i);
- p->m_nLightId = ld;
- p->getTurn();
- // 3. 设置灯组中ld号灯的颜色为lc,其他为lc_
- debug_print_syslog(0,"lamp light: changeGroup light id: %d, set lc: %d, lc_: %d",ld,lc, lc_);
- p->setAvoidance(ld,lc,lc_);
- p->releaseTurn();
- }
- void AvoidanceRule::eraseTwoGroup(std::shared_ptr<card_interface> &c,std::vector<std::shared_ptr<TrafficLightGroup>> &vt)
- {
- eraseTrafficLightGroup(true,c,vt);
- eraseTrafficLightGroup(false,c,vt);
- }
- void AvoidanceRule::eraseTrafficLightGroup(bool a,std::shared_ptr<card_interface> &c,std::vector<std::shared_ptr<TrafficLightGroup>> &vt)
- {
- std::shared_ptr<TrafficLightGroup> p = nullptr;
- bool flag = false;
- if(a)
- {
- p = c->front();
- c->pop_front();
- }
- else
- {
- p = c->back();
- c->pop_back();
- }
- p->getTurn();
- if(p->load()<=2)
- {
- debug_print_syslog(0, "lamp light: eraseTrafficLightGroup group id: %d, card: %s",p->m_gId, c->cardId().c_str());
- p->resetGroup();// 重置灯组
- flag = true;
- }
- p->releaseTurn();
- p->set_status(false);
- if(flag)
- vt.push_back(p);
- }
- // 根据车辆与灯组的位置关系,查找灯组
- std::vector<std::shared_ptr<TrafficLightGroup>> AvoidanceRule::findGroup(double x,double y,int areaid,double vv, std::shared_ptr<card_interface> c)
- {
- debug_print_syslog(0,"lamp light: AvoidanceRule::findGroup: x: %.3f,y: %.3f,areaid: %d,vv: %.3f,line: %d",x,y,areaid,vv,__LINE__);
- std::vector<std::shared_ptr<TrafficLightGroup>> arr;
- auto v = m_CTrafficLightGroupMap[areaid]; // 获取车辆所在地图区域内的所有红绿灯组
- double d= 0;
- for(std::size_t i = 0;i<v.size();i++)
- {
- //如果此灯组被控制了,则不允许使用
- if (v[i]->get_status()&&v[i]->m_sCardId != c->cardId())
- {
- debug_print_syslog(0, "red green: has control this light group");
- continue;
- }
- d = v[i]->dist_direct(x,y); // 求灯组到车辆的距离(车辆在灯组的左下方,则距离值取反)
- if(d<=0) // 车辆在灯组左边或下边
- {
- if(vv>0) // 速度方向与前进方向一致
- {
- if(v[i]->dist(x,y)<=ConfStruct::getCs().max_scope_bigCar ) // 车辆到灯组的距离小于100
- arr.push_back( v[i]);
- if(i+1<v.size()) //紧挨着的一个灯组到车辆距离小于100
- if(v[i+1]->dist(x,y)<=ConfStruct::getCs().max_scope_bigCar )
- arr.push_back(v[i+1]);
- }
- else if(vv<0) // 速度方向与前进方向不一致,判断运动方向的灯组是否在可控范围
- {
- if(i>=1 && v[i-1]->dist(x,y)<=ConfStruct::getCs().max_scope_bigCar)
- arr.push_back(v[i-1]);
- if(i>=2&& v[i-2]->dist(x,y)<=ConfStruct::getCs().max_scope_bigCar )
- arr.push_back(v[i-2]);
- }
- break;
- }
- }
- if(d>0) // 车辆在灯组右边或上边
- {
- if(vv<0)
- {
- std::size_t i = v.size();
- if(i>=1 && v[i-1]->dist(x,y)<=ConfStruct::getCs().max_scope_bigCar )
- arr.push_back(v[i-1]);
- if(i>=2&&v[i-2]->dist(x,y)<=ConfStruct::getCs().max_scope_bigCar )
- arr.push_back(v[i-2]);
- }
- }
- return std::move(arr);
- }
- bool AvoidanceRule::getMidCar(std::shared_ptr<card_interface> bigcar,std::shared_ptr<TrafficLightGroup> & one,std::shared_ptr<TrafficLightGroup> & two)
- {
- //get dist between tow groups
- double dist = one->dist(*two);
- //use geo_hash get intersection vector..
- auto vt_one = find_near(static_cast<int>(one->x),static_cast<int>(one->y),static_cast<int>(dist),itostr(one->m_gId));
- auto vt_two = find_near(static_cast<int>(two->x),static_cast<int>(two->y),static_cast<int>(dist),itostr(two->m_gId));
- vt_one.erase(std::remove_if(vt_one.begin(),vt_one.end(),[](const std::string &name){
- if(0 == name.compare(0,3,"002"))
- return false;
- else
- return true;}),vt_one.end());
- vt_two.erase(std::remove_if(vt_two.begin(),vt_two.end(),[](const std::string &name){
- if(0 == name.compare(0,3,"002"))
- return false;
- else
- return true;}),vt_two.end());
- std::sort(vt_one.begin(),vt_one.end());
- std::sort(vt_two.begin(),vt_two.end());
- std::vector<std::string> vt_intersection;
- do{
- std::set_intersection(vt_one.begin(),vt_one.end(),
- vt_two.begin(),vt_two.end(),std::back_inserter(vt_intersection));
- if(vt_intersection.empty()) break;
- //筛选出符合条件的车辆
- vt_intersection.erase(std::remove_if(vt_intersection.begin(),vt_intersection.end(),[&](const std::string &cardno)->bool{
- auto cardPtr = getCard(cardno);
- if(cardPtr == nullptr)
- return true;
- return findTwoLightGroupMidCar(one,two,bigcar,cardPtr);
- }),vt_intersection.end());
- //离第一个红绿灯距离进行排序
- }while(false);
- if(vt_intersection.empty())
- return false;
- else
- return true;
- }
- //后续小车避让大车规则,只需要找到前方的两个红绿灯,找到两个对比一下之前的记录,如果灯组改变了,则修改,如果没变,则判断是否有小车,进行改变
- //如果只找到一个红绿灯,查看是否含有记录,如果有,则不坐任何处理。
- bool AvoidanceRule::findTwoLightGroupMidCar(std::shared_ptr<TrafficLightGroup> one,std::shared_ptr<TrafficLightGroup>two,std::shared_ptr<card_interface> bigcar,std::shared_ptr<card_interface> car)
- {
- bool flag = true;
- double x = car->getX();
- double y = car->getY();
- double v = car->getv();
- double vv = bigcar->getv();
- double d = one->dist(x,y);
- line l(*one,*two);
- if(l.contain(x,y,1))
- {
- if(v*vv<0 && d > ConfStruct::getCs().mid_car_length_goroup)
- flag = false;
- }
-
- return flag;
- }
- std::vector<std::string> DecoratorRule::find_near(double x,double y,double dist,std::string cardid)
- {
- auto v = m_->find_near(x,y,dist,cardid);
- return std::move(v);
- }
- std::shared_ptr<card_interface> DecoratorRule::getCard(const std::string &card_no)
- {
- return m_->getCard(card_no);
- }
- void DecoratorRuleCrossing::run()
- {
- while(!b_exit)
- {
- //do handle crossingRule.
- auto vt = m_rule->handleRule();
- m_->getSendLightInfo(std::move(vt),"Crossing");
- std::this_thread::sleep_for(std::chrono::seconds(2));
- }
- }
- void DecoratorRuleAvoidance::handleRule(std::shared_ptr<card_interface> c)
- {
- static bool f = false;
- if(!f){std::dynamic_pointer_cast<AvoidanceRule>(m_rule)->sort();f=true;}
- if(c==nullptr)
- return ;
- if(!c->getBigCarFlag())
- return;
- auto vt = m_rule->handleRule(c);
- if(vt.size()>0){
- debug_print_syslog(0,"lamp light: gid: %d, size: %d",vt[0]->getId(),vt.size());
- }
-
- m_->getSendLightInfo(std::move(vt),"Avoidance");
- }
- std::shared_ptr<RunRedLight> DecoratorRuleAvoidance::check_run_red_light(std::shared_ptr<card_interface> c,double dis)
- {
- static bool f = false;
- if(!f){std::dynamic_pointer_cast<AvoidanceRule>(m_rule)->sort();f=true;}
- if(c==nullptr)
- return nullptr;
- return m_rule->check_run_red_light(c, dis);
- }
- NAMESPACE_POINT_END(NAMESPACE_POINT)
- #if 0
- //4,'name','label','state',4727, 275, 0, 10, 200, '2018-04-18 11:18:12',90
- void InitData::read_dat_group(const char * fname)
- {
- FILE *fp = fopen(fname,"r");
- char buf[512];
- int32_t t,id,areaid,mapid,ctime;
- double x,y,scope;
- char* s[20];
- while(fgets(buf,sizeof(buf),fp))
- {
- t=str_split(buf,&s[0]);
- if(t<8)
- continue;
- id = atoi(s[0]);
- x = atof(s[4]);
- y = -atof(s[5]);
- scope = atof(s[7]);
- mapid = atoi(s[10]);
- areaid = atoi(s[11]);
- ctime = atoi(s[12]);
- std::cout << s[0] <<' '<< s[4] <<' ' << s[5] <<' '<<s[7] <<std::endl;
- //crossing
- std::shared_ptr<TrafficLightGroup> tmp = nullptr;
- //if(scope != 0)
- //{
- tmp = std::make_shared<TrafficLightGroup>(x,y,0.0,id,mapid,areaid,scope,ctime);
- // m_CrossingMap.push_back(tmp);
- //}
- // else
- // tmp = std::make_shared<AvoidanceTrafficLightGroup>(x,y,0,id,mapid,areaid);
- m_Map.insert({id,tmp});
- }
- }
- //3, '192.168.1.101', 4727, 100,0,'name','label',100,'state',1,60,'2017/08/10 11:11:11',4,0
- void InitData::read_dat_light(const char * fname)
- {
- FILE *fp = fopen(fname,"r");
- char buf[512];
- int t,id,readerid,gid,specialFlag;
- double x,y;
- std::string ip;
- char* s[20];
- while(fgets(buf,sizeof(buf),fp))
- {
- t=str_split(buf,&s[0]);
- if(t<8)
- continue;
- id = atoi(s[0]);
- ip = s[1];
- x = atof(s[2]);
- y= -atof(s[3]);
- //mapid = atoi(s[7]);
- readerid = atoi(s[7]);
- //areaid = atoi(s[9]);
- //controltime = atoi(s[10]);
- gid = atoi(s[12]);
- specialFlag = atoi(s[13]);//0正常1表示特殊红绿灯
- std::cout << id <<' '<< ip <<' ' << x <<' '<< y <<' ' << readerid <<' ' <<gid <<std::endl;
- std::shared_ptr<TrafficLight> tmp = std::make_shared<TrafficLight>(id,x,y,0,readerid,ip,specialFlag);
- m_Map[gid]->put(tmp);
- }
- }
- int main()
- {
- std::shared_ptr<Manage> m = std::make_shared<Manage>();
- //test point func
- TrafficLightGroup *ctlg = new TrafficLightGroup(1,1,0,12,12.5,5,10,90) ;
- std::cout <<"direct:"<< ctlg->dist_direct(3,1)<<std::endl;;
- delete ctlg;
- //test self-thread.
- //std::shared_ptr<Rule> r =std::make_shared<CrossingRule> ();
- //DecoratorRule* drc = new DecoratorRuleCrossing(&m);
- //drc->CreateRule();
- //drc->handleRule();
- //delete drc;
- //test line
- line l(point(100,10),point(120,10));
- std::cout << l.dist(point(130,10))<<std::endl;
- line ll(point(4727,75),point(4727,88));
- std::cout << ll.a<<' '<<ll.b<<' '<<ll.c<<"=illlll"<<std::endl;
- auto abc = point(4727,75).get_abc(point(4727,88));
- std::cout << std::get<0>(abc)<<' '<<std::get<1>(abc)<<' '<<std::get<2>(abc)<<std::endl;
- line lll(point(4729,75),point(4729,88));
- std::cout << lll.a<<' '<<lll.b<<' '<<lll.c<<"=iixxlllll"<<std::endl;
- //read config
- InitData Id;
- Id.read_dat_group("dat_group.txt");
- Id.read_dat_light("dat_light.txt");
- Id.showInfo();
- //get map for trafficLightGroups includes TrafficLights
- //std::shared_ptr<Rule> CrossingR = std::make_shared<CrossingRule>(m);
- //CrossingR->put(std::move(Id.m_CrossingMap));
- //std::shared_ptr<Rule> AvoidanceR = std::make_shared<AvoidanceRule>(m);
- uint64_t tt = time(NULL)*1000;
- std::shared_ptr<card_interface> bc24 = std::make_shared<c>("2:4",tt,4470,10,true,-1.1,1);//cardid timet x y bigcar speed,areaid
- std::shared_ptr<card_interface> bc22 = std::make_shared<c>("2:2",tt,4650,75,false,1.1,2);//cardid timet x y bigcar speed.areaid
- m->m_map.insert({"2:4",bc24});
- m->m_map.insert({"2:2",bc22});
- // CrossingR->update(4470,-75,"2:4");
- // 这里需要把y转化成-
- m->m_g.update(4650,-75,"2:2");
- //auto av = AvoidanceR->find_near(4600,-75,100,"2:4");
- std::shared_ptr<DecoratorRule> DecCrossingRule = std::make_shared<DecoratorRuleCrossing>(m);
- std::shared_ptr<DecoratorRule> DecAvoidanceRule = std::make_shared<DecoratorRuleAvoidance>(m);
- DecCrossingRule->CreateRule();
- DecAvoidanceRule->CreateRule();
- for(const auto px : Id.m_Map)
- {
- if(px.second->m_gId == 1)
- {
- px.second->store(3);
- px.second->m_controlTime = time(NULL)+30;
- }
- if(px.second->m_gId == 1)
- bc24->push_back(px.second);
- if(px.second->m_gId == 2)
- {
- //px.second->store(2);
- bc24->push_back(px.second);
- }
- // if(px.second->m_gId == 6)
- // {
- // bc24->push_back(px.second);
- // px.second->store(3);
- // }
- DecAvoidanceRule->put(px.second);
- DecCrossingRule->put(px.second);
- }
- //DectoratorRule do next..
- // DecCrossingRule->handleRule();
- //DecAvoidanceRule->handleRule();
- #if 0
- //test the sort for TrafficLightGroup............
- std::shared_ptr<TrafficLightGroup> p = std::make_shared<CrossingTrafficLightGroup>(1,2,0,12,12.5,5,10);
- std::shared_ptr<TrafficLightGroup> p1 = std::make_shared<AvoidanceTrafficLightGroup>(2,2,0,12,5,10);
- std::shared_ptr<TrafficLightGroup> p2 = std::make_shared<CrossingTrafficLightGroup>(3,2,0,12,12.5,5,10);
- std::vector<std::shared_ptr<TrafficLightGroup>> vp;
- vp.push_back(p);
- vp.push_back(p2);
- vp.push_back(p1);
- for(auto px:vp)
- std::cout << px->x<<"beforefdfdfd" << px->y<<std::endl;
- std::sort(vp.begin(),vp.end(),[](std::shared_ptr<TrafficLightGroup> one,std::shared_ptr<TrafficLightGroup> two)->bool{std::cout << two->x<<std::endl;return *one<*two;});
- for(auto px:vp)
- std::cout << px->x<<"fdfdfd" << px->y<<std::endl;
- #endif
- //DecAvoidanceRule->handleRule(bc24);
- std::dynamic_pointer_cast<c>(bc24)->x_ = 4727;
- m->m_g.update(4727,-10,"2:4");
- //m->m_g.update(4604,-75,"2:4");
- std::cout <<"------------------------------------"<<std::endl;
- // DecAvoidanceRule->handleRule(bc24);
- DecCrossingRule->handleRule();
- std::cout<<"******************************************************************************888"<<std::endl;
- std::cout << DecCrossingRule->showInfo()<<std::endl;;
- std::cout<<"************************888"<<std::endl;
- // std::cout << DecAvoidanceRule->showInfo()<<std::endl;;
- std::cout<<"**********************************************888"<<std::endl;
- std::this_thread::sleep_for(std::chrono::seconds(20));
- m->m_g.update(4604,-75,"2:4");
- while(1){std::this_thread::sleep_for(std::chrono::seconds(10));};
- return 0;
- }
- #endif
|