|
@@ -2,6 +2,7 @@
|
|
#include "module_traffic_light_rule.h"
|
|
#include "module_traffic_light_rule.h"
|
|
#include "module_traffic_light_manager.h"
|
|
#include "module_traffic_light_manager.h"
|
|
|
|
|
|
|
|
+// 车辆与指定灯组g距离比较,lhs近则返回true,否则返回false
|
|
bool rule::sort_vehicle(const uint64_t lhs, const uint64_t rhs, const traffic_light_group_ptr& g)
|
|
bool rule::sort_vehicle(const uint64_t lhs, const uint64_t rhs, const traffic_light_group_ptr& g)
|
|
{
|
|
{
|
|
pos_data* v1 = traffic_light_manager::instance()->get_position(lhs);
|
|
pos_data* v1 = traffic_light_manager::instance()->get_position(lhs);
|
|
@@ -17,6 +18,17 @@ bool rule::sort_vehicle(const uint64_t lhs, const uint64_t rhs, const traffic_li
|
|
return d1 < d2;
|
|
return d1 < d2;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+// 根据车辆等级进行排序
|
|
|
|
+bool rule::sort_vehicle_by_level(const uint64_t lhs, const uint64_t rhs, const traffic_light_group_ptr& g)
|
|
|
|
+{
|
|
|
|
+ //pos_data* lp = traffic_light_manager::instance()->get_position(lhs);
|
|
|
|
+ //pos_data* rp = traffic_light_manager::instance()->get_position(rhs);
|
|
|
|
+
|
|
|
|
+ //return lp->
|
|
|
|
+ return true;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// 从灯组g中找到最近的灯
|
|
traffic_light_ptr rule::find_nearby_light(const point& p, traffic_light_group_ptr g)
|
|
traffic_light_ptr rule::find_nearby_light(const point& p, traffic_light_group_ptr g)
|
|
{
|
|
{
|
|
traffic_light_ptr pl = nullptr;
|
|
traffic_light_ptr pl = nullptr;
|
|
@@ -35,6 +47,7 @@ traffic_light_ptr rule::find_nearby_light(const point& p, traffic_light_group_pt
|
|
return pl;
|
|
return pl;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+// 设置灯的颜色
|
|
void crossing_rule::change_state(const uint64_t vid, traffic_light_group_ptr g)
|
|
void crossing_rule::change_state(const uint64_t vid, traffic_light_group_ptr g)
|
|
{
|
|
{
|
|
pos_data* cp = traffic_light_manager::instance()->get_position(vid);
|
|
pos_data* cp = traffic_light_manager::instance()->get_position(vid);
|
|
@@ -44,7 +57,7 @@ void crossing_rule::change_state(const uint64_t vid, traffic_light_group_ptr g)
|
|
// 设置来车方向为绿灯,其他方向为红灯
|
|
// 设置来车方向为绿灯,其他方向为红灯
|
|
if(nullptr != pl){
|
|
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", vid, pl->m_light_id);
|
|
- g->set_light(pl->m_light_id, green, red);
|
|
|
|
|
|
+ g->set_light(pl->m_light_id, light_shape::green_all_on, light_shape::red_all_on);
|
|
}
|
|
}
|
|
}else{
|
|
}else{
|
|
log_warn("[traffic_light] it can't get vehicle position. vid=%lld, lg's id=%d", vid, g->m_group_id);
|
|
log_warn("[traffic_light] it can't get vehicle position. vid=%lld, lg's id=%d", vid, g->m_group_id);
|
|
@@ -63,7 +76,8 @@ bool crossing_rule::get_vehicle_state(const uint64_t& vid)
|
|
|
|
|
|
return s;
|
|
return s;
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+// 从红绿灯组中找距离最近的红绿灯
|
|
|
|
+// 后续改为找上行或下行灯
|
|
bool crossing_rule::find_light(const uint64_t& vid, traffic_light_group_ptr g, bool a)
|
|
bool crossing_rule::find_light(const uint64_t& vid, traffic_light_group_ptr g, bool a)
|
|
{
|
|
{
|
|
pos_data* cp = traffic_light_manager::instance()->get_position(vid);
|
|
pos_data* cp = traffic_light_manager::instance()->get_position(vid);
|
|
@@ -99,6 +113,7 @@ bool crossing_rule::find_light(const uint64_t& vid, traffic_light_group_ptr g, b
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+// 手工控制
|
|
bool crossing_rule::handle_manual_ctrl(traffic_light_group_ptr g)
|
|
bool crossing_rule::handle_manual_ctrl(traffic_light_group_ptr g)
|
|
{
|
|
{
|
|
if(g->is_time_out()){
|
|
if(g->is_time_out()){
|
|
@@ -109,135 +124,327 @@ bool crossing_rule::handle_manual_ctrl(traffic_light_group_ptr g)
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
-bool crossing_rule::handle_crossing(traffic_light_group_ptr g)
|
|
|
|
|
|
+bool crossing_rule::handle_crossing(traffic_light_group_ptr group)
|
|
{
|
|
{
|
|
- if(g->m_scope <= 0){
|
|
|
|
|
|
+ if(group->m_scope <= 0){
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
+
|
|
// 查找一定范围的车辆
|
|
// 查找一定范围的车辆
|
|
- std::vector<uint64_t> vtl = traffic_light_manager::instance()->find_nearby_vehicle(point(static_cast<int>(g->x), static_cast<int>(g->y)), g->m_scope, 0);
|
|
|
|
- log_info("[traffic_light] handle crossing rule.gid=%d, group_scope=%.2f, vehicle's num=%d", g->m_group_id, g->m_scope, vtl.size());
|
|
|
|
|
|
+ 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());
|
|
if(vtl.empty()){
|
|
if(vtl.empty()){
|
|
- if(g->m_card_id > 0 && g->m_priority == priority_crossing)
|
|
|
|
|
|
+ if(group->m_card_id > 0 && group->m_priority == priority_crossing)
|
|
{
|
|
{
|
|
// 释放红绿灯组
|
|
// 释放红绿灯组
|
|
- g->reset();
|
|
|
|
|
|
+ group->reset();
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
- // 是否已经有车记录
|
|
|
|
- if(g->m_card_id > 0)
|
|
|
|
|
|
+ // 是否已经有原控制车辆记录
|
|
|
|
+ if(group->m_card_id > 0)
|
|
{
|
|
{
|
|
- auto it = std::find(vtl.begin(), vtl.end(), g->m_card_id);
|
|
|
|
|
|
+ // check stream
|
|
|
|
+ if(group->get_stream_state() != group->get_stream(group->m_card_id)){
|
|
|
|
+ log_info("[traffic_light] %d's vehicle is passed crossing that is gid=%d, old_stream=%d, cur_stream=%d",group->m_card_id, group->m_group_id, group->get_stream_state(), group->get_stream(group->m_card_id));
|
|
|
|
+ traffic_light_manager::instance()->vtlg_erase(group->m_card_id, group);
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ auto it = std::find(vtl.begin(), vtl.end(), group->m_card_id);
|
|
if(it != vtl.end()){
|
|
if(it != vtl.end()){
|
|
- log_info("[traffic_light] handle crossing rule, there has vehicle that control the light group, card_id=%d", g->m_card_id);
|
|
|
|
|
|
+ log_info("[traffic_light] handle crossing rule, there has vehicle that control the light group, card_id=%d", group->m_card_id);
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
std::sort(vtl.begin(), vtl.end(), [&](const uint64_t& lhs, const uint64_t& rhs){
|
|
std::sort(vtl.begin(), vtl.end(), [&](const uint64_t& lhs, const uint64_t& rhs){
|
|
- return sort_vehicle(lhs, rhs, g);
|
|
|
|
|
|
+ return sort_vehicle(lhs, rhs, group);
|
|
});
|
|
});
|
|
|
|
|
|
- // 设置优先级以及卡id
|
|
|
|
- g->set_crossing(vtl[0], priority_crossing);
|
|
|
|
- // 修改红绿灯组状态
|
|
|
|
- change_state(vtl[0], g);
|
|
|
|
|
|
+ move_stream ms = group->get_stream(vtl[0]);
|
|
|
|
+
|
|
|
|
+ pos_data* p = traffic_light_manager::instance()->get_position(vtl[0]);
|
|
|
|
+ if((group->m_card_id == 0) && (p->m_speed * p->dist_direct(*group) < 0)){
|
|
|
|
+ log_info("[traffic_light] gid=%d is not same to vehicle=%d direction", group->m_group_id, p->m_card_id);
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 对需要控制的N个灯组进行控制
|
|
|
|
+ std::vector<traffic_light_group_ptr> vt_groups = traffic_light_manager::instance()->find_stream_groups(group, ms);
|
|
|
|
+ if(vt_groups.empty()){
|
|
|
|
+ log_info("[traffic_light] 找不到灯组");
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ std::string s = "[";
|
|
|
|
+ for_each(vt_groups.begin(), vt_groups.end(), [&s](traffic_light_group_ptr g){ s.append(std::to_string(g->m_group_id));});
|
|
|
|
+ s.append("]");
|
|
|
|
+ log_info("[traffic_light] the %d's vehicle control light group of %s", vtl[0], s.c_str());
|
|
|
|
+
|
|
|
|
+ for(auto it : vt_groups){
|
|
|
|
+ traffic_light_manager::instance()->vtlg_insert(vtl[0], it);
|
|
|
|
+ it->set_crossing(vtl[0], priority_crossing);
|
|
|
|
+ it->set_stream_state(ms);
|
|
|
|
+ change_state(vtl[0], it);
|
|
|
|
+ }
|
|
|
|
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+//避让规则处理
|
|
|
|
+//1)车辆等级规则
|
|
|
|
+//2)上下行规则
|
|
bool crossing_rule::handle_avoidance(traffic_light_group_ptr g)
|
|
bool crossing_rule::handle_avoidance(traffic_light_group_ptr g)
|
|
{
|
|
{
|
|
- // 查看是否是大车,true表示特殊红绿灯,需要检测大车避让规则
|
|
|
|
- bool flag = false;
|
|
|
|
|
|
+ if(g->m_card_id == 0){
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
|
|
- do{
|
|
|
|
- auto vt = traffic_light_manager::instance()->find_nearby_vehicle(point(static_cast<int>(g->x), static_cast<int>(g->y)), g->m_scope, 0);
|
|
|
|
- log_info("[traffic_light] handle avoidance, gid=%d, x=%.2f, y=%.2f, scope=%.2f, vehicle's size=%d", g->m_group_id, g->x, g->y, g->m_scope, vt.size());
|
|
|
|
- // 筛选大车
|
|
|
|
- if(vt.empty()){
|
|
|
|
- flag = true;
|
|
|
|
- break;
|
|
|
|
|
|
+ bool ret = false;
|
|
|
|
+ ret = avoidance_by_level(g);
|
|
|
|
+ if(ret){
|
|
|
|
+ return ret;
|
|
|
|
+ }else{
|
|
|
|
+ return avoidance_by_updown(g);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// 根据车辆等级处理避让
|
|
|
|
+bool crossing_rule::avoidance_by_level(traffic_light_group_ptr& group)
|
|
|
|
+{
|
|
|
|
+ // 根据车辆等级处理避让规则
|
|
|
|
+ // 查找红绿灯组附近车辆
|
|
|
|
+ auto vt = 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);
|
|
|
|
+
|
|
|
|
+ // 红绿灯组附近无车辆
|
|
|
|
+ if(vt.empty()){
|
|
|
|
+ if(priority_avoidance == group->get_priority() && group->m_card_id > 0){
|
|
|
|
+ bool exist = traffic_light_manager::instance()->vtlg_exist(group->m_card_id, group->m_group_id);
|
|
|
|
+ if(!exist){
|
|
|
|
+ // 重置灯组控制权
|
|
|
|
+ group->reset();
|
|
|
|
+ }
|
|
}
|
|
}
|
|
- vt.erase(std::remove_if(vt.begin(), vt.end(), [&](const uint64_t& vid){
|
|
|
|
- return get_vehicle_state(vid);
|
|
|
|
- }),
|
|
|
|
- vt.end());
|
|
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ 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);
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
|
|
- if(vt.empty()){
|
|
|
|
- flag = true;
|
|
|
|
- break;
|
|
|
|
|
|
+ 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());
|
|
|
|
+
|
|
|
|
+ if(group->m_card_id > 0 && get_vehicle_state(group->m_card_id)){
|
|
|
|
+ //检查是否释放控制权
|
|
|
|
+ if(group->get_stream_state() != move_stream::unknown)
|
|
|
|
+ {
|
|
|
|
+ // 如果车辆运行方向与灯组上下行方向不一致,则重置
|
|
|
|
+ if(group->get_stream_state() != group->get_stream(group->m_card_id))
|
|
|
|
+ {
|
|
|
|
+ traffic_light_manager::instance()->vtlg_erase(group->m_card_id, group);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
|
|
- // 查看离最近的点是否为特殊点,判断位置是否在直线上,判断方向
|
|
|
|
|
|
+ bool exist_bigger_car = false;
|
|
|
|
+ if(group->m_card_id == 0){
|
|
|
|
+ for(size_t i = 0;i < vt.size(); ++i){
|
|
|
|
+ if(get_vehicle_state(vt[i])){
|
|
|
|
+ exist_bigger_car = true;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if(exist_bigger_car || (group->m_card_id > 0 && !get_vehicle_state(group->m_card_id))){
|
|
|
|
+ // only keep vehicle's state that is bigger flag
|
|
vt.erase(std::remove_if(vt.begin(), vt.end(), [&](const uint64_t& vid){
|
|
vt.erase(std::remove_if(vt.begin(), vt.end(), [&](const uint64_t& vid){
|
|
- return find_light(vid, g);
|
|
|
|
|
|
+ if(get_vehicle_state(vid)){
|
|
|
|
+ return false;
|
|
|
|
+ }else{
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
}),
|
|
}),
|
|
vt.end());
|
|
vt.end());
|
|
|
|
+
|
|
if(vt.empty()){
|
|
if(vt.empty()){
|
|
- flag = true;
|
|
|
|
- break;
|
|
|
|
|
|
+ return false;
|
|
}
|
|
}
|
|
-
|
|
|
|
- // 特殊规则保留id且优先级2,避让规则置空id,优先级2
|
|
|
|
- if(priority_avoidance == g->get_priority()){
|
|
|
|
- if(0 == g->m_card_id){
|
|
|
|
- break;
|
|
|
|
- }else{
|
|
|
|
- auto it = std::find(vt.begin(), vt.end(), g->m_card_id);
|
|
|
|
- if(it != vt.end()){
|
|
|
|
- break;
|
|
|
|
|
|
+ }
|
|
|
|
+ // 删除不在红绿灯组所在路径上的车辆
|
|
|
|
+ vt.erase(std::remove_if(vt.begin(), vt.end(), [&](const uint64_t& vid){
|
|
|
|
+ pos_data* p = traffic_light_manager::instance()->get_position(vid);
|
|
|
|
+ if(group->is_at_path(*p)){
|
|
|
|
+ return false;
|
|
|
|
+ }else{
|
|
|
|
+ return true;
|
|
}
|
|
}
|
|
|
|
+ }),
|
|
|
|
+ vt.end());
|
|
|
|
+ if(vt.empty()){
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 排序,找到离之最近的大车
|
|
|
|
+ std::sort(vt.begin(), vt.end(), [&](const uint64_t& vid, const uint64_t& cid){
|
|
|
|
+ return sort_vehicle(vid, cid, group);
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ move_stream ms = group->get_stream(vt[0]);
|
|
|
|
+ if(ms == move_stream::unknown){
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 对需要控制的N个灯组进行控制
|
|
|
|
+ std::vector<traffic_light_group_ptr> vt_groups = traffic_light_manager::instance()->find_stream_groups(group, ms);
|
|
|
|
+ if(vt_groups.empty()){
|
|
|
|
+ log_info("[traffic_light] 找不到灯组");
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ std::string s = "[";
|
|
|
|
+ for_each(vt_groups.begin(), vt_groups.end(), [&s](traffic_light_group_ptr g){ s.append(std::to_string(g->m_group_id));});
|
|
|
|
+ s.append("]");
|
|
|
|
+ log_info("[traffic_light] the %d's vehicle control light group of %s", vt[0], s.c_str());
|
|
|
|
+
|
|
|
|
+ for(auto& it : vt_groups){
|
|
|
|
+ traffic_light_manager::instance()->vtlg_insert(vt[0], it);
|
|
|
|
+ it->set_crossing(vt[0], priority_avoidance);
|
|
|
|
+ it->set_stream_state(ms);
|
|
|
|
+ change_state(vt[0], it);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return true;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// 根据车辆上下行处理避让
|
|
|
|
+bool crossing_rule::avoidance_by_updown(traffic_light_group_ptr& group)
|
|
|
|
+{
|
|
|
|
+ // 1.检查控制灯组的车辆是否为上行车,如果是,则直接返回,表示上行车辆已控制灯组
|
|
|
|
+ // 2.如果是下行车,则查看新车辆是否为上行,如果是,则控制
|
|
|
|
+ if(group->m_card_id){
|
|
|
|
+ if(group->get_stream(group->m_card_id) == move_stream::up_stream){
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ //检查是否释放控制权
|
|
|
|
+ if(group->get_stream_state() != group->get_stream(group->m_card_id))
|
|
|
|
+ {
|
|
|
|
+ traffic_light_manager::instance()->vtlg_erase(group->m_card_id, group);
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ auto vt = 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);
|
|
|
|
+ if(vt.empty()){
|
|
|
|
+ if(priority_avoidance == group->get_priority() && group->m_card_id > 0){
|
|
|
|
+ bool exist = traffic_light_manager::instance()->vtlg_exist(group->m_card_id, group->m_group_id);
|
|
|
|
+ if(!exist){
|
|
|
|
+ // 重置灯组控制权
|
|
|
|
+ group->reset();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
|
|
- // 排序,找到离之最近的大车
|
|
|
|
- std::sort(vt.begin(), vt.end(), [&](const uint64_t& vid, const uint64_t& cid){
|
|
|
|
- return sort_vehicle(vid, cid, g);
|
|
|
|
- });
|
|
|
|
|
|
+ log_info("[traffic_light] handle avoidance_by_updown, gid=%d, x=%.2f, y=%.2f, scope=%.2f, vehicle's size=%d", group->m_group_id, group->x, group->y, group->m_scope, vt.size());
|
|
|
|
|
|
- change_state(vt[0], g);
|
|
|
|
- g->set_crossing(vt[0], priority_avoidance);
|
|
|
|
|
|
+ bool exist_up_stream = false;
|
|
|
|
+ if(group->m_card_id == 0){
|
|
|
|
+ for(size_t i = 0; i < vt.size(); ++i){
|
|
|
|
+ if(group->get_stream(vt[i]) == move_stream::up_stream){
|
|
|
|
+ exist_up_stream = true;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
|
|
- return true;
|
|
|
|
- }while(false);
|
|
|
|
|
|
+ if(exist_up_stream || group->m_card_id > 0){
|
|
|
|
+ // erase vehicles that's state of down_stream
|
|
|
|
+ vt.erase(std::remove_if(vt.begin(), vt.end(), [&](uint64_t cid){
|
|
|
|
+ if(group->get_stream(cid) == move_stream::down_stream){
|
|
|
|
+ return true;
|
|
|
|
+ }else{
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ }));
|
|
|
|
|
|
- if(flag){
|
|
|
|
- // 找不到之前的车辆,则初始化
|
|
|
|
- if(priority_avoidance == g->get_priority() && g->m_card_id > 0){
|
|
|
|
- g->reset();
|
|
|
|
- }else{
|
|
|
|
- flag = false;
|
|
|
|
|
|
+ if(vt.empty()){
|
|
|
|
+ return false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- return flag;
|
|
|
|
|
|
+ log_info("[traffic_light] the number of vehicle that's state of up_stream = %d", vt.size());
|
|
|
|
+ for(size_t i = 0;i < group->m_path.size();i++){
|
|
|
|
+ log_info("%s", group->m_path[i].to_str().c_str());
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 根据车辆远近进行排序
|
|
|
|
+ std::sort(vt.begin(), vt.end(), [&](const uint64_t& vid, const uint64_t& cid){
|
|
|
|
+ return sort_vehicle(vid, cid, group);
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ // 每辆车上下行处理
|
|
|
|
+ // 根据点与灯组的带方向距离和灯组中上行灯与下行灯之间的带方向距离信息,来判断车辆行径方向是上行or下行
|
|
|
|
+ // 判断位置与红绿灯组的方向与速度得方向是否一致
|
|
|
|
+ // 如果车辆静止不动的话,不考虑
|
|
|
|
+
|
|
|
|
+ move_stream ms = group->get_stream(vt[0]);
|
|
|
|
+ // 对需要控制的N个灯组进行控制
|
|
|
|
+ std::vector<traffic_light_group_ptr> vt_groups = traffic_light_manager::instance()->find_stream_groups(group, ms);
|
|
|
|
+ if(vt_groups.empty()){
|
|
|
|
+ log_info("[traffic_light] 找不到灯组");
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ std::string s = "[";
|
|
|
|
+ for_each(vt_groups.begin(), vt_groups.end(), [&s](traffic_light_group_ptr g){ s.append(std::to_string(g->m_group_id));});
|
|
|
|
+ s.append("]");
|
|
|
|
+ log_info("[traffic_light] the %d's vehicle control light group of %s", vt[0], s.c_str());
|
|
|
|
+
|
|
|
|
+ for(auto& it : vt_groups){
|
|
|
|
+ if(it->m_card_id == 0
|
|
|
|
+ || (ms == move_stream::up_stream && it->get_stream_state() == move_stream::down_stream)
|
|
|
|
+ )
|
|
|
|
+ {
|
|
|
|
+ // 以下两种情况,改变灯组的控制权
|
|
|
|
+ // 1.车辆为上行;
|
|
|
|
+ // 2.灯组无控制权
|
|
|
|
+ traffic_light_manager::instance()->vtlg_insert(vt[0], it);
|
|
|
|
+ it->get_turn();
|
|
|
|
+ it->set_crossing(vt[0], priority_avoidance);
|
|
|
|
+ it->set_stream_state(ms);
|
|
|
|
+ change_state(vt[0], it);
|
|
|
|
+
|
|
|
|
+ log_info("[traffic_light] vehicle get group control, cid = %d, group_id=%d", vt[0], it->m_group_id);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return true;
|
|
}
|
|
}
|
|
|
|
|
|
-vt_traffic_group crossing_rule::handle_rule(pos_data& p)
|
|
|
|
|
|
+void crossing_rule::handle_rule(pos_data& p)
|
|
{
|
|
{
|
|
- vt_traffic_group llist;
|
|
|
|
- log_info("[traffic_light] crossing_rule::handle_rule, group's size=%d", m_vt_group.size());
|
|
|
|
|
|
+ //log_info("[traffic_light] crossing_rule::handle_rule, group's size=%d", m_vt_group.size());
|
|
for(auto& it : m_vt_group){
|
|
for(auto& it : m_vt_group){
|
|
// 获取控制权
|
|
// 获取控制权
|
|
it->get_turn();
|
|
it->get_turn();
|
|
int priority = it->get_priority();
|
|
int priority = it->get_priority();
|
|
- log_info("[traffic_light] crossing_rule::handle_rule, gid=%d, priority=%d, special=%d", it->m_group_id, priority, it->m_special);
|
|
|
|
|
|
+ //log_info("[traffic_light] crossing_rule::handle_rule, gid=%d, priority=%d, special=%d", it->m_group_id, priority, it->m_special);
|
|
bool flag = false;
|
|
bool flag = false;
|
|
while(true){
|
|
while(true){
|
|
if(priority_manual_ctrl == priority){
|
|
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);
|
|
|
|
- if(flag){
|
|
|
|
|
|
+ flag = handle_manual_ctrl(it);
|
|
|
|
+ log_info("[traffic_light] crossing_rule::handle_rule, after call handle_manual_ctrl, flag=%d", flag);
|
|
|
|
+ if(flag){
|
|
break;
|
|
break;
|
|
- }
|
|
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
- if(priority <= priority_avoidance && it->m_special){
|
|
|
|
|
|
+ if(priority <= priority_avoidance){
|
|
flag = handle_avoidance(it);
|
|
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){
|
|
if(flag){
|
|
@@ -255,16 +462,17 @@ vt_traffic_group crossing_rule::handle_rule(pos_data& p)
|
|
|
|
|
|
break;
|
|
break;
|
|
};
|
|
};
|
|
-
|
|
|
|
|
|
+
|
|
it->release_turn();
|
|
it->release_turn();
|
|
- if(flag){
|
|
|
|
- llist.push_back(it);
|
|
|
|
- }
|
|
|
|
}
|
|
}
|
|
|
|
+}
|
|
|
|
|
|
- return std::move(llist);
|
|
|
|
|
|
+std::shared_ptr<run_red_light> crossing_rule::check_run_red_light(pos_data& p)
|
|
|
|
+{
|
|
|
|
+ return nullptr;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+// 查找灯组
|
|
vt_traffic_group avoidance_rule::find_group(const pos_data& p)
|
|
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);
|
|
return find_group(point(p.x, p.y), p.m_area_id, p.m_speed, p);
|
|
@@ -349,6 +557,7 @@ bool avoidance_rule::find_vehicle_in_group(vt_traffic_group& vg, std::vector<pos
|
|
log_error("[traffic_light] vv's size less than 2");
|
|
log_error("[traffic_light] vv's size less than 2");
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
+
|
|
bool flag = true;
|
|
bool flag = true;
|
|
double d = vg[0]->dist(vv[1].x, vv[1].y);
|
|
double d = vg[0]->dist(vv[1].x, vv[1].y);
|
|
line tl(*vg[0], *vg[1]);
|
|
line tl(*vg[0], *vg[1]);
|
|
@@ -384,7 +593,7 @@ bool avoidance_rule::get_vehicle(const pos_data& p, vt_traffic_group& vg)
|
|
vti.erase(std::remove_if(vti.begin(), vti.end(), [&](const uint64_t& vid) -> bool {
|
|
vti.erase(std::remove_if(vti.begin(), vti.end(), [&](const uint64_t& vid) -> bool {
|
|
pos_data* tp = traffic_light_manager::instance()->get_position(vid);
|
|
pos_data* tp = traffic_light_manager::instance()->get_position(vid);
|
|
if(tp == nullptr){
|
|
if(tp == nullptr){
|
|
- return true;
|
|
|
|
|
|
+ return true;
|
|
}
|
|
}
|
|
|
|
|
|
std::vector<pos_data> vv;
|
|
std::vector<pos_data> vv;
|
|
@@ -477,12 +686,12 @@ bool avoidance_rule::is_different(traffic_light_group_ptr g, const point& p, con
|
|
return b;
|
|
return b;
|
|
}
|
|
}
|
|
|
|
|
|
-vt_traffic_group avoidance_rule::handle_rule(pos_data& p)
|
|
|
|
|
|
+void avoidance_rule::handle_rule(pos_data& p)
|
|
{
|
|
{
|
|
vt_traffic_group llist;
|
|
vt_traffic_group llist;
|
|
|
|
|
|
if(p.m_card_id == 0|| p.m_type == 0){
|
|
if(p.m_card_id == 0|| p.m_type == 0){
|
|
- return std::move(llist);
|
|
|
|
|
|
+ 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", m_map_area_group.size(), p.m_area_id);
|
|
@@ -628,20 +837,11 @@ vt_traffic_group avoidance_rule::handle_rule(pos_data& p)
|
|
p.m_light_group.push_back(vtg[0]->m_group_id);
|
|
p.m_light_group.push_back(vtg[0]->m_group_id);
|
|
p.m_light_group.push_back(vtg[1]->m_group_id);
|
|
p.m_light_group.push_back(vtg[1]->m_group_id);
|
|
}
|
|
}
|
|
- }
|
|
|
|
- else
|
|
|
|
- {
|
|
|
|
- if(p.m_light_group.front() == vtg[0]->m_group_id){
|
|
|
|
- erase(false, p, llist);
|
|
|
|
- insert(vtg[1], p, llist, green, spark);
|
|
|
|
- }else{
|
|
|
|
- erase(true, p, llist);
|
|
|
|
- if(vtg[0]->get_priority() <= priority_avoidance){
|
|
|
|
- change_group(vtg[0], point(p.x, p.y), la, lb);
|
|
|
|
- llist.push_back(vtg[0]);
|
|
|
|
- }
|
|
|
|
- insert(vtg[1], p, llist, green, spark);
|
|
|
|
|
|
+ if(vtg[0]->get_priority() <= priority_avoidance){
|
|
|
|
+ change_group(vtg[0], point(p.x, p.y), la, lb);
|
|
|
|
+ llist.push_back(vtg[0]);
|
|
}
|
|
}
|
|
|
|
+ insert(vtg[1], p, llist, green, spark);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
else
|
|
@@ -652,17 +852,6 @@ vt_traffic_group avoidance_rule::handle_rule(pos_data& p)
|
|
}else{
|
|
}else{
|
|
erase(true, p, llist);
|
|
erase(true, p, llist);
|
|
}
|
|
}
|
|
-
|
|
|
|
- if(vtg[1]->get_priority() <= priority_avoidance){
|
|
|
|
- change_group(vtg[1], point(p.x, p.y), green, spark);
|
|
|
|
- llist.push_back(vtg[1]);
|
|
|
|
- }
|
|
|
|
- p.m_light_group.push_front(vtg[1]->m_group_id);
|
|
|
|
- if(vtg[0]->get_priority() < priority_avoidance){
|
|
|
|
- change_group(vtg[0], point(p.x, p.y), la, lb);
|
|
|
|
- llist.push_back(vtg[0]);
|
|
|
|
- }
|
|
|
|
- }else{
|
|
|
|
erase(true, p, llist);
|
|
erase(true, p, llist);
|
|
erase(true, p, llist);
|
|
erase(true, p, llist);
|
|
insert(vtg[0], p, llist, la, lb);
|
|
insert(vtg[0], p, llist, la, lb);
|
|
@@ -676,6 +865,10 @@ vt_traffic_group avoidance_rule::handle_rule(pos_data& p)
|
|
}else{
|
|
}else{
|
|
log_info("[traffic_light] the %d area has no light group", p.m_area_id);
|
|
log_info("[traffic_light] the %d area has no light group", p.m_area_id);
|
|
}
|
|
}
|
|
|
|
+}
|
|
|
|
|
|
- return std::move(llist);
|
|
|
|
|
|
+std::shared_ptr<run_red_light> avoidance_rule::check_run_red_light(pos_data& p)
|
|
|
|
+{
|
|
|
|
+ return nullptr;
|
|
}
|
|
}
|
|
|
|
+
|