| | |
| | | #include "net.h" |
| | | #include "../jni_log.h" |
| | | |
| | | #define DEBUG(fmt, args...) LOGD("<net> <%s>: " fmt, __func__, ##args) |
| | | |
| | | using namespace std; |
| | | |
| | | /************************************************************* |
| | |
| | | bool found_first = false; |
| | | |
| | | if ((hptr = gethostbyname(host_name)) == NULL) { |
| | | LOGE("gethostbyname error\n"); |
| | | DEBUG("gethostbyname error\n"); |
| | | return -1; |
| | | } |
| | | |
| | | LOGD("official hostname: %s\n", hptr->h_name); |
| | | DEBUG("official hostname: %s\n", hptr->h_name); |
| | | |
| | | for (pptr = hptr->h_aliases; *pptr != NULL; pptr++) { |
| | | LOGD("alias:%s\n", *pptr); |
| | | DEBUG("alias:%s\n", *pptr); |
| | | } |
| | | |
| | | switch(hptr->h_addrtype) |
| | |
| | | case AF_INET: |
| | | { |
| | | for (pptr = hptr->h_addr_list; *pptr != NULL; pptr++) { |
| | | LOGD("addrsss:%s\n", inet_ntop(hptr->h_addrtype, *pptr, str, sizeof(str))); |
| | | DEBUG("addrsss:%s\n", inet_ntop(hptr->h_addrtype, *pptr, str, sizeof(str))); |
| | | if (!found_first) { |
| | | strcpy(net_addr, str); |
| | | found_first = true; |
| | |
| | | } |
| | | case AF_INET6: |
| | | default: |
| | | LOGD("unknown address type\n"); |
| | | DEBUG("unknown address type\n"); |
| | | break; |
| | | } |
| | | |
| | |
| | | |
| | | // int value, value_len; |
| | | // getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, &value_len); |
| | | // LOGD("keepalive 0 %d", value); |
| | | // DEBUG("keepalive 0 %d", value); |
| | | |
| | | // value = 128; |
| | | // setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, sizeof(value)); |
| | | // LOGD("keepalive 1 %d", value); |
| | | // DEBUG("keepalive 1 %d", value); |
| | | |
| | | // getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, &value_len); |
| | | // LOGD("keepalive 1 %d", value); |
| | | // DEBUG("keepalive 1 %d", value); |
| | | |
| | | |
| | | /* Set: use keepalive on fd, default 0 */ |
| | | alive = 1; |
| | | if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &alive, sizeof(alive)) != 0) |
| | | { |
| | | LOGE("TCP Set keepalive error"); |
| | | DEBUG("TCP Set keepalive error"); |
| | | return -1; |
| | | } |
| | | /* 20 Seconds not data, send keeplive packet, default 7200 */ |
| | | idle = 20; |
| | | if (setsockopt (fd, SOL_TCP, TCP_KEEPIDLE, &idle, sizeof(idle)) != 0) |
| | | { |
| | | LOGE("TCP Set keepalive idle error"); |
| | | DEBUG("TCP Set keepalive idle error"); |
| | | return -1; |
| | | } |
| | | /* If not recv respond, After 5 seconds retry, default 75 */ |
| | | intv = 5; |
| | | if (setsockopt (fd, SOL_TCP, TCP_KEEPINTVL, &intv, sizeof(intv)) != 0) |
| | | { |
| | | LOGE("TCP Set keepalive intv error"); |
| | | DEBUG("TCP Set keepalive intv error"); |
| | | return -1; |
| | | } |
| | | /* If try 9 times and fail, we consider the tcp is disconnected, default 9 */ |
| | | cnt = 9; |
| | | if (setsockopt (fd, SOL_TCP, TCP_KEEPCNT, &cnt, sizeof(cnt)) != 0) |
| | | { |
| | | LOGE("TCP Set keepalive cnt error"); |
| | | DEBUG("TCP Set keepalive cnt error"); |
| | | return -1; |
| | | } |
| | | |
| | | /* int timeout = 10000; // 10秒 |
| | | if (setsockopt (fd, IPPROTO_TCP, TCP_USER_TIMEOUT, &timeout, sizeof(timeout)) != 0) |
| | | { |
| | | LOGE("TCP Set keepalive timeout error"); |
| | | DEBUG("TCP Set keepalive timeout error"); |
| | | return -1; |
| | | }*/ |
| | | |
| | | LOGD("TCP Set keepalive OK"); |
| | | DEBUG("TCP Set keepalive OK"); |
| | | |
| | | return 0; |
| | | } |
| | |
| | | int error_value; |
| | | socklen_t error_value_len; |
| | | |
| | | LOGI("%s", __func__); |
| | | DEBUG("tcp_connect... %s : %d", ip, port); |
| | | |
| | | error_value_len = sizeof( error_value ); |
| | | |
| | | if((soc = socket(PF_INET, SOCK_STREAM, 0)) == -1) |
| | | { |
| | | LOGE("%s: socket", __func__); |
| | | DEBUG("%s: socket", __func__); |
| | | return -1; |
| | | } |
| | | |
| | |
| | | // Set non-blocking |
| | | if( (arg = fcntl(soc, F_GETFL, NULL)) < 0) |
| | | { |
| | | LOGE("%s: fcntl( F_GETFL ) error", __func__); |
| | | DEBUG("%s: fcntl( F_GETFL ) error", __func__); |
| | | goto TCP_CONNECT_1; |
| | | } |
| | | |
| | | if( fcntl(soc, F_SETFL, arg | O_NONBLOCK) < 0) |
| | | { |
| | | LOGE( "%s: fcntl( F_SETFL ) error", __func__); |
| | | DEBUG( "%s: fcntl( F_SETFL ) error", __func__); |
| | | goto TCP_CONNECT_1; |
| | | } |
| | | |
| | |
| | | |
| | | if(fds_ret < 0) |
| | | { |
| | | LOGE( "%s: TCP select error", __func__); |
| | | DEBUG( "%s: TCP select error", __func__); |
| | | goto TCP_CONNECT_1; |
| | | } |
| | | else if(fds_ret == 0) |
| | | { |
| | | LOGE("%s: TCP Connect Timeout %ld", __func__, tv.tv_sec); |
| | | DEBUG("%s: TCP Connect Timeout %ld", __func__, tv.tv_sec); |
| | | goto TCP_CONNECT_1; |
| | | } |
| | | else if(FD_ISSET(soc, &rdfds)) |
| | |
| | | } |
| | | else |
| | | { |
| | | LOGE("%s: some error occur in tcp_connect()", __func__); |
| | | DEBUG("%s: some error occur in tcp_connect()", __func__); |
| | | goto TCP_CONNECT_1; |
| | | } |
| | | |
| | |
| | | arg &= ~O_NONBLOCK; |
| | | if( fcntl(soc, F_SETFL, arg) < 0) |
| | | { |
| | | LOGE( "%s: fcntl( F_SETFL ) error", __func__); |
| | | DEBUG( "%s: fcntl( F_SETFL ) error", __func__); |
| | | goto TCP_CONNECT_1; |
| | | } |
| | | |
| | | LOGI("%s: tcp connected %s: %d", __func__, ip, port); |
| | | DEBUG("%s: tcp connected %s: %d", __func__, ip, port); |
| | | |
| | | return( soc ); |
| | | |
| | |
| | | fds_ret = select(fd + 1, NULL, &rdfds, NULL, &tv); |
| | | |
| | | if (fds_ret < 0) { |
| | | LOGE("tcp error send select error"); |
| | | DEBUG("tcp error send select error"); |
| | | return -1; |
| | | } else if(fds_ret == 0) { |
| | | LOGE("tcp error Occur failure(such as line disconnect)"); |
| | | DEBUG("tcp error Occur failure(such as line disconnect)"); |
| | | //Occur failure(such as line disconnect) |
| | | ret = -1; |
| | | } else if(FD_ISSET(fd, &rdfds)) { |
| | | ret = send(fd, buf, len, 0); |
| | | if(ret == -1) { |
| | | LOGE("tcp error TCP Send Error"); |
| | | DEBUG("tcp error TCP Send Error"); |
| | | } |
| | | } else { |
| | | LOGE("tcp error tcp send has error\n"); |
| | | DEBUG("tcp error tcp send has error\n"); |
| | | } |
| | | |
| | | return ret; |
| | |
| | | |
| | | void DisconnectTCP(int fd) |
| | | { |
| | | LOGI("DisconnectTCP fd = %d", fd); |
| | | DEBUG("DisconnectTCP fd = %d", fd); |
| | | if (fd >= 0) { |
| | | shutdown(fd, SHUT_RDWR); |
| | | close(fd); |
| | |
| | | |
| | | if (fds_ret < 0) |
| | | { |
| | | LOGE("UDP send select error"); |
| | | DEBUG("UDP send select error"); |
| | | return -1; |
| | | } |
| | | else if(fds_ret == 0) |
| | | { |
| | | LOGE("Occur failure(such as line disconnect)"); |
| | | DEBUG("Occur failure(such as line disconnect)"); |
| | | ret = -1; |
| | | } |
| | | else if(FD_ISSET(fd, &rdfds)) |
| | |
| | | |
| | | if(ret == -1) |
| | | { |
| | | LOGE("UDP Send Error"); |
| | | DEBUG("UDP Send Error"); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | LOGE("UDP send has error\n"); |
| | | DEBUG("UDP send has error\n"); |
| | | } |
| | | |
| | | return ret; |
| | |
| | | if (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN) { |
| | | return 0; |
| | | } else { |
| | | LOGE("UDP ERROR!! = %d", errno); |
| | | DEBUG("UDP ERROR!! = %d", errno); |
| | | return -1; |
| | | } |
| | | } |
| | |
| | | static LIST_AREA_MAP AreaMapList; |
| | | |
| | | static Polygon RoadMapPoints; |
| | | static road_exam_map RoadMap; |
| | | |
| | | static LIST_ROAD_MAP RoadMapList; |
| | | |
| | |
| | | RoadMapPoints.num = 0; |
| | | RoadMapPoints.point = NULL; |
| | | |
| | | RoadMapList.clear(); |
| | | // RoadMapList.clear(); |
| | | RoadMap.roads.clear(); |
| | | RoadMap.specialAreas.clear(); |
| | | RoadMap.triggerLines.clear(); |
| | | |
| | | CarSensorInit(); |
| | | |
| | |
| | | { |
| | | if (ExamStart) return; |
| | | |
| | | DEBUG("清除旧的路考地图"); |
| | | |
| | | if (RoadMapPoints.point != NULL) { |
| | | free(RoadMapPoints.point); |
| | | } |
| | | RoadMapPoints.num = 0; |
| | | |
| | | for (int i = 0; i < RoadMap.roads.size(); ++i) { |
| | | for (int j = 0; j < RoadMap.roads[i].leftEdge.size(); ++j) { |
| | | RoadMap.roads[i].leftEdge[j].points.clear(); |
| | | vector<PointF>().swap(RoadMap.roads[i].leftEdge[j].points); |
| | | } |
| | | RoadMap.roads[i].leftEdge.clear(); |
| | | vector<edge_t>().swap(RoadMap.roads[i].leftEdge); |
| | | |
| | | for (int j = 0; j < RoadMap.roads[i].rightEdge.size(); ++j) { |
| | | RoadMap.roads[i].rightEdge[j].points.clear(); |
| | | vector<PointF>().swap(RoadMap.roads[i].rightEdge[j].points); |
| | | } |
| | | RoadMap.roads[i].rightEdge.clear(); |
| | | vector<edge_t>().swap(RoadMap.roads[i].rightEdge); |
| | | |
| | | for (int j = 0; j < RoadMap.roads[i].separate.size(); ++j) { |
| | | for (int k = 0; k < RoadMap.roads[i].separate[j].lines.size(); ++k) { |
| | | for (int m = 0; m < RoadMap.roads[i].separate[j].lines[k].size(); ++m) { |
| | | RoadMap.roads[i].separate[j].lines[k][m].points.clear(); |
| | | vector<PointF>().swap(RoadMap.roads[i].separate[j].lines[k][m].points); |
| | | } |
| | | |
| | | RoadMap.roads[i].separate[j].lines[k].clear(); |
| | | vector<segment_t>().swap(RoadMap.roads[i].separate[j].lines[k]); |
| | | } |
| | | RoadMap.roads[i].separate[j].lines.clear(); |
| | | vector<vector<segment_t>>().swap(RoadMap.roads[i].separate[j].lines); |
| | | } |
| | | RoadMap.roads[i].separate.clear(); |
| | | vector<separate_t>().swap(RoadMap.roads[i].separate); |
| | | } |
| | | |
| | | RoadMap.roads.clear(); |
| | | vector<road_t>().swap(RoadMap.roads); |
| | | |
| | | for (int i = 0; i < RoadMap.specialAreas.size(); ++i) { |
| | | RoadMap.specialAreas[i].area.clear(); |
| | | vector<PointF>().swap(RoadMap.specialAreas[i].area); |
| | | } |
| | | RoadMap.specialAreas.clear(); |
| | | vector<special_area_t>().swap(RoadMap.specialAreas); |
| | | |
| | | RoadMap.triggerLines.clear(); |
| | | vector<trigger_line_t>().swap(RoadMap.triggerLines); |
| | | /* |
| | | for (int i = 0; i < RoadMapList.size(); ++i) { |
| | | struct road_exam_map map = RoadMapList[i]; |
| | | |
| | |
| | | } |
| | | } |
| | | |
| | | RoadMapList.clear(); |
| | | RoadMapList.clear();*/ |
| | | } |
| | | |
| | | void SetRoadMap(road_exam_map &map) |
| | | { |
| | | if (ExamStart) return; |
| | | |
| | | RoadMap.roads.assign(map.roads.begin(), map.roads.end()); |
| | | RoadMap.specialAreas.assign(map.specialAreas.begin(), map.specialAreas.end()); |
| | | RoadMap.triggerLines.assign(map.triggerLines.begin(), map.triggerLines.end()); |
| | | |
| | | DEBUG("得到新的路考地图 路数量 %d 特殊区域数量 %d 触发线数量 %d", RoadMap.roads.size(), RoadMap.specialAreas.size(), RoadMap.triggerLines.size()); |
| | | } |
| | | |
| | | void SetRoadMapPoints(vector<double> &mapPoints) |
| | |
| | | vector<int> area, |
| | | vector<int> stopLine) |
| | | { |
| | | struct road_exam_map newMap; |
| | | /* struct road_exam_map newMap; |
| | | |
| | | newMap.id = id; |
| | | newMap.type = type; |
| | |
| | | newMap.stopLine.Y2); |
| | | } |
| | | |
| | | RoadMapList.push_back(newMap); |
| | | RoadMapList.push_back(newMap);*/ |
| | | } |
| | | |
| | | void SetCarMeasurePoint(double *basePoint, int *axial, int *left_front_tire, |
| | |
| | | // err = true; |
| | | // MA_SendExamStatus(0, -3); |
| | | } |
| | | if (type != TEST_TYPE_AREA && (RoadMapPoints.num == 0 || RoadMapPoints.point == NULL || RoadMapList.size() == 0)) { |
| | | if (type != TEST_TYPE_AREA && RoadMap.roads.size() == 0) { |
| | | DEBUG("没有路考地图"); |
| | | err = true; |
| | | MA_SendExamStatus(0, -1); |
| | |
| | | brief.pointNum = CarModel->pointNum; |
| | | brief.point = (double *) malloc(CarModel->pointNum * 2 * sizeof(double)); |
| | | for (int i = 0, j = 0; i < CarModel->pointNum; ++i) { |
| | | brief.point[j++] = CarModel->carXY[i].X; |
| | | brief.point[j++] = CarModel->carXY[i].Y; |
| | | brief.point[j++] = round(CarModel->carXY[i].X, 4); |
| | | brief.point[j++] = round(CarModel->carXY[i].Y, 4); |
| | | } |
| | | |
| | | MA_SendCarPosition(&brief); |
| | |
| | | // 汇报灯光考试结束 |
| | | if (exam_dummy_light == 2) { |
| | | DEBUG("灯光考试结束"); |
| | | InitRoadExam(); |
| | | InitRoadExam(RoadMap); |
| | | } |
| | | } |
| | | } |
| | |
| | | |
| | | if (ExamType != TEST_TYPE_AREA) { |
| | | if (exam_dummy_light == 2) { |
| | | TestRoadGeneral(RoadMapList, CarModel, CarModelList, speed, move, rtkTime); |
| | | // TestRoadGeneral(RoadMapList, CarModel, CarModelList, speed, move, rtkTime); |
| | | TestRoadGeneral(RoadMap, CarModel, CarModelList, speed, move, rtkTime); |
| | | } |
| | | } else { |
| | | TestAreaGeneral(AreaMapList, CarModel, CarModelList, speed, move, azimuth, rtkTime); |
| | |
| | | int wrong_id; |
| | | }; |
| | | |
| | | struct trigger_line_t { |
| | | |
| | | struct trigger_line_tx { |
| | | int triggerMapId; |
| | | Polygon line; |
| | | }; |
| | | |
| | | struct road_exam_map { |
| | | |
| | | struct road_exam_mapx { |
| | | int id; |
| | | int type; |
| | | |
| | |
| | | Polygon *redArea; |
| | | |
| | | int triggerLineNum; |
| | | trigger_line_t *triggerLine; |
| | | trigger_line_tx *triggerLine; |
| | | |
| | | int roadEdgeLineNum; // 道路边线,只有直线驾驶、靠边停车才有 |
| | | Polygon *roadEdgeLine; |
| | |
| | | int flagStop; // 到达开始线前,是否需要停车 |
| | | }; |
| | | |
| | | typedef vector<struct road_exam_map> LIST_ROAD_MAP; |
| | | typedef vector<struct road_exam_mapx> LIST_ROAD_MAP; |
| | | |
| | | #define ROAD_DOTTED_LINE 0 |
| | | #define ROAD_SOLID_LINE 1 |
| | | #define LINE_DOTTED 0 |
| | | #define LINE_SOLID 1 |
| | | #define LINE_HALF_SOLID_LEFT 2 |
| | | #define LINE_HALF_SOLID_RIGHT 3 |
| | | |
| | | //车道方向(按位组合),如果为0,则表无车道方向说明; |
| | | #define LANE_FORWARD 0x01 |
| | | #define LANE_LEFT 0x02 |
| | | #define LANE_RIGHT 0x04 |
| | | #define LANE_BACKWARD 0x08 |
| | | |
| | | #define ZEBRA_CROSSING 0 |
| | | #define SCHOOL_AREA 1 |
| | | #define BUS_STATION_AREA 2 |
| | | #define GRID_AREA 3 |
| | | |
| | | typedef struct { |
| | | int character; // 属性(实线、虚线,有些可以掉头的路段) |
| | |
| | | } edge_t; |
| | | |
| | | typedef struct { |
| | | int character; // 属性《实线、虚线》 |
| | | std::vector<Polygon> lines; // 每一条线 |
| | | int character; // 属性《实线、虚线、半实半虚线》 |
| | | int left_lane_direct; |
| | | int right_lane_direct; |
| | | std::vector<PointF> points; |
| | | } segment_t; |
| | | |
| | | // 一组平行的分道线 |
| | | typedef struct { |
| | | std::vector<std::vector<segment_t>> lines; // 每段域下的平行的一组线 |
| | | } separate_t; |
| | | |
| | | struct road_t { |
| | | typedef struct { |
| | | int id; |
| | | Line startLine; |
| | | Line stopLine; |
| | | int active; // 到达路口尾部的行进方向 |
| | | int targetRoad; |
| | | int stopFlag; |
| | | string tts; |
| | | Polygon area; |
| | | Polygon area; // 整个道路区域 |
| | | std::vector<edge_t> leftEdge; |
| | | std::vector<edge_t> rightEdge; |
| | | std::vector<separate_t> separate; |
| | | }; |
| | | } road_t; |
| | | |
| | | struct special_area_t { |
| | | typedef struct { |
| | | int id; |
| | | int road; |
| | | int character; |
| | | Line startLine; |
| | | Polygon area; |
| | | }; |
| | | int type; |
| | | std::vector<PointF> area; // 人行道等右侧2点,网格线4点 |
| | | std::vector<PointF> leftPoints; // 对应到道路左侧的点 |
| | | } special_area_t; |
| | | |
| | | struct trigger2_line_t { |
| | | typedef struct { |
| | | int id; |
| | | int road; |
| | | int active; |
| | | string tts; |
| | | Line line; |
| | | }; |
| | | } trigger_line_t; |
| | | |
| | | struct road_exam2_map { |
| | | std::vector<struct road_t> roads; |
| | | std::vector<struct special_area_t> specialAreas; |
| | | std::vector<struct trigger2_line_t> triggerLines; |
| | | struct road_exam_map { |
| | | std::vector<road_t> roads; |
| | | std::vector<special_area_t> specialAreas; |
| | | std::vector<trigger_line_t> triggerLines; |
| | | }; |
| | | |
| | | struct area_exam_map { |
| | |
| | | |
| | | |
| | | void CleanRoadMap(void); |
| | | void SetRoadMap(road_exam_map &map); |
| | | |
| | | void SetRoadMapPoints(vector<double> &mapPoints); |
| | | void AddRoadMapParent(int id, int type, string tts, int stopFlag, vector<vector<int>> &redLines, |
| | | vector<vector<int>> &redAreas, vector<vector<int>> &greenLines, |
| | |
| | | #define ID_SM_RTK_PLAT_LOGIN 0x0005 |
| | | #define ID_SM_READ_MAP 0x0006 |
| | | #define ID_MS_MAP 0x8006 |
| | | #define ID_MS_ROAD_MAP 0x8013 |
| | | #define ID_MS_ROAD_MAP 0x8014 |
| | | #define ID_MS_ROAD_MAP2 0x8013 |
| | | |
| | | #define ID_SM_READ_CAR 0x0007 |
| | | #define ID_MS_CAR 0x8007 |
| | |
| | | } |
| | | break; |
| | | } |
| | | case ID_MS_ROAD_MAP2: { |
| | | Document doc; |
| | | doc.Parse(value); |
| | | if (!doc.HasParseError()) { |
| | | DEBUG("开始解析路考地图"); |
| | | |
| | | vector<PointF> mapPoints; |
| | | mapPoints.clear(); |
| | | |
| | | if (doc.HasMember("points")) { |
| | | const Value &s = doc["points"]; |
| | | |
| | | DEBUG("得到所有点 共 %d", s.Size()/2); |
| | | |
| | | int n = 0; |
| | | PointF temp; |
| | | |
| | | // X-Y坐标集合 |
| | | for (Value::ConstValueIterator itr = s.Begin(); |
| | | itr != s.End(); ++itr, ++n) { |
| | | if ((n % 2) == 0) { |
| | | temp.X = (*itr).GetDouble(); |
| | | } else { |
| | | temp.Y = (*itr).GetDouble(); |
| | | mapPoints.push_back(temp); |
| | | } |
| | | } |
| | | } |
| | | |
| | | road_exam_map map; |
| | | |
| | | map.roads.clear(); |
| | | map.specialAreas.clear(); |
| | | map.triggerLines.clear(); |
| | | |
| | | if (doc.HasMember("road")) { |
| | | const Value &a = doc["road"]; |
| | | |
| | | if (a.IsArray()) { |
| | | for (Value::ConstValueIterator itr = a.Begin(); itr != a.End(); ++itr) { |
| | | road_t road; |
| | | |
| | | if (itr->HasMember("id")) { |
| | | const Value &s = (*itr)["id"]; |
| | | DEBUG("路id %d", s.GetInt()); |
| | | road.id = s.GetInt(); |
| | | } |
| | | if (itr->HasMember("start_line")) { |
| | | const Value &a2 = (*itr)["start_line"]; |
| | | |
| | | PointF p1, p2; |
| | | int n = 0; |
| | | |
| | | for (Value::ConstValueIterator itr2 = a2.Begin(); itr2 != a2.End(); ++itr2, ++n) { |
| | | DEBUG("起始线 %d", (*itr2).GetInt()); |
| | | if (n == 0) { |
| | | p1 = mapPoints[(*itr2).GetInt()]; |
| | | } else if (n == 1) { |
| | | p2 = mapPoints[(*itr2).GetInt()]; |
| | | } |
| | | } |
| | | |
| | | MakeLine(&road.startLine, &p1, &p2); |
| | | } |
| | | if (itr->HasMember("stop_line")) { |
| | | const Value &a2 = (*itr)["stop_line"]; |
| | | |
| | | PointF p1, p2; |
| | | int n = 0; |
| | | |
| | | for (Value::ConstValueIterator itr2 = a2.Begin(); itr2 != a2.End(); ++itr2, ++n) { |
| | | DEBUG("结束线 %d", (*itr2).GetInt()); |
| | | if (n == 0) { |
| | | p1 = mapPoints[(*itr2).GetInt()]; |
| | | } else if (n == 1) { |
| | | p2 = mapPoints[(*itr2).GetInt()]; |
| | | } |
| | | } |
| | | |
| | | MakeLine(&road.stopLine, &p1, &p2); |
| | | } |
| | | if (itr->HasMember("active")) { |
| | | const Value &s = (*itr)["active"]; |
| | | DEBUG("路口动作 %d", s.GetInt()); |
| | | |
| | | road.active = s.GetInt(); |
| | | } |
| | | if (itr->HasMember("tts")) { |
| | | const Value &s = (*itr)["tts"]; |
| | | road.tts = s.GetString(); |
| | | } |
| | | if (itr->HasMember("stop_flag")) { |
| | | const Value &s = (*itr)["stop_flag"]; |
| | | road.stopFlag = s.GetInt(); |
| | | } |
| | | if (itr->HasMember("next_road")) { |
| | | const Value &s = (*itr)["next_road"]; |
| | | road.targetRoad = s.GetInt(); |
| | | } |
| | | if (itr->HasMember("left_edge")) { |
| | | const Value &a2 = (*itr)["left_edge"]; |
| | | DEBUG("左边线"); |
| | | |
| | | if (a2.IsArray()) { |
| | | for (Value::ConstValueIterator itr2 = a2.Begin(); itr2 != a2.End(); ++itr2) { |
| | | edge_t edge; |
| | | |
| | | if (itr2->HasMember("type")) { |
| | | const Value &s = (*itr2)["type"]; |
| | | DEBUG("\t类型 %d", s.GetInt()); |
| | | |
| | | edge.character = s.GetInt(); |
| | | } |
| | | if (itr2->HasMember("line")) { |
| | | const Value &a3 = (*itr2)["line"]; |
| | | if (a3.IsArray()) { |
| | | for (Value::ConstValueIterator itr3 = a3.Begin(); itr3 != a3.End(); ++itr3) { |
| | | DEBUG("\t线点 %d", (*itr3).GetInt()); |
| | | edge.points.push_back(mapPoints[(*itr3).GetInt()]); |
| | | } |
| | | } |
| | | } |
| | | |
| | | road.leftEdge.push_back(edge); |
| | | } |
| | | } |
| | | } |
| | | if (itr->HasMember("right_edge")) { |
| | | const Value &a2 = (*itr)["right_edge"]; |
| | | DEBUG("右边线"); |
| | | if (a2.IsArray()) { |
| | | for (Value::ConstValueIterator itr2 = a2.Begin(); itr2 != a2.End(); ++itr2) { |
| | | edge_t edge; |
| | | |
| | | if (itr2->HasMember("type")) { |
| | | const Value &s = (*itr2)["type"]; |
| | | DEBUG("\t类型 %d", s.GetInt()); |
| | | edge.character = s.GetInt(); |
| | | } |
| | | if (itr2->HasMember("line")) { |
| | | const Value &a3 = (*itr2)["line"]; |
| | | if (a3.IsArray()) { |
| | | for (Value::ConstValueIterator itr3 = a3.Begin(); itr3 != a3.End(); ++itr3) { |
| | | DEBUG("\t线点 %d", (*itr3).GetInt()); |
| | | edge.points.push_back(mapPoints[(*itr3).GetInt()]); |
| | | } |
| | | } |
| | | } |
| | | |
| | | road.rightEdge.push_back(edge); |
| | | } |
| | | } |
| | | } |
| | | if (itr->HasMember("separate")) { |
| | | const Value &a2 = (*itr)["separate"]; |
| | | DEBUG("段数量 %d", a2.Size()); |
| | | |
| | | for (Value::ConstValueIterator itr2 = a2.Begin(); itr2 != a2.End(); ++itr2) { |
| | | DEBUG("\t线数量 %d", (*itr2).Size()); |
| | | separate_t sep; |
| | | |
| | | for (Value::ConstValueIterator itr3 = (*itr2).Begin(); itr3 != (*itr2).End(); ++itr3) { |
| | | DEBUG("\t\t节数量 %d", (*itr3).Size()); |
| | | vector<segment_t> sline; |
| | | |
| | | for (Value::ConstValueIterator itr4 = (*itr3).Begin(); itr4 != (*itr3).End(); ++itr4) { |
| | | const Value &type = (*itr4)["type"]; |
| | | const Value &line = (*itr4)["line"]; |
| | | |
| | | segment_t seg; |
| | | |
| | | DEBUG("\t\t\t节类型 = %d", type.GetInt()); |
| | | seg.character = type.GetInt(); |
| | | |
| | | if ((*itr4).HasMember("left_lane_direct")) { |
| | | const Value &dir = (*itr4)["left_lane_direct"]; |
| | | DEBUG("\t\t\t左车道方向 %d", dir.GetInt()); |
| | | seg.left_lane_direct = dir.GetInt(); |
| | | } else { |
| | | seg.left_lane_direct = 0; |
| | | } |
| | | |
| | | if ((*itr4).HasMember("right_lane_direct")) { |
| | | const Value &dir = (*itr4)["right_lane_direct"]; |
| | | DEBUG("\t\t\t右车道方向 %d", dir.GetInt()); |
| | | seg.right_lane_direct = dir.GetInt(); |
| | | } else { |
| | | seg.right_lane_direct = 0; |
| | | } |
| | | |
| | | for (Value::ConstValueIterator itr5 = line.Begin(); itr5 != line.End(); ++itr5) { |
| | | DEBUG("\t\t\t点 = %d", (*itr5).GetInt()); |
| | | |
| | | seg.points.push_back(mapPoints[(*itr5).GetInt()]); |
| | | } |
| | | |
| | | sline.push_back(seg); |
| | | } |
| | | sep.lines.push_back(sline); |
| | | } |
| | | |
| | | road.separate.push_back(sep); |
| | | } |
| | | } |
| | | |
| | | map.roads.push_back(road); |
| | | } |
| | | } |
| | | } |
| | | |
| | | if (doc.HasMember("special_area")) { |
| | | const Value &a = doc["special_area"]; |
| | | |
| | | vector<special_area_t> specialAreas; |
| | | |
| | | for (Value::ConstValueIterator itr = a.Begin(); |
| | | itr != a.End(); ++itr) { |
| | | special_area_t specialArea; |
| | | |
| | | if (itr->HasMember("type")) { |
| | | const Value &s = (*itr)["type"]; |
| | | specialArea.type = s.GetInt(); |
| | | } |
| | | if (itr->HasMember("id")) { |
| | | const Value &s = (*itr)["id"]; |
| | | specialArea.id = s.GetInt(); |
| | | } |
| | | if (itr->HasMember("road")) { |
| | | const Value &s = (*itr)["road"]; |
| | | specialArea.road = s.GetInt(); |
| | | } |
| | | |
| | | if (itr->HasMember("area")) { |
| | | const Value &a2 = (*itr)["area"]; |
| | | |
| | | for (Value::ConstValueIterator itr2 = a2.Begin(); |
| | | itr2 != a2.End(); ++itr2) { |
| | | specialArea.area.push_back(mapPoints[(*itr2).GetInt()]); |
| | | } |
| | | } |
| | | |
| | | map.specialAreas.push_back(specialArea); |
| | | } |
| | | } |
| | | if (doc.HasMember("trigger_line")) { |
| | | |
| | | } |
| | | DEBUG("地图解析完毕"); |
| | | |
| | | CleanRoadMap(); |
| | | SetRoadMap(map); |
| | | } else { |
| | | DEBUG("############## 地图解析出错###################"); |
| | | } |
| | | |
| | | break; |
| | | } |
| | | case ID_MS_MAP: { |
| | | Document doc; |
| | | doc.Parse(value); |
| | |
| | | #include <malloc.h> |
| | | #include <initializer_list> |
| | | #include <cctype> |
| | | #include <iosfwd> |
| | | #include <iomanip> |
| | | #include <sstream> |
| | | |
| | | #include "../jni_log.h" |
| | | |
| | |
| | | inline double toDegree(double radians) |
| | | { |
| | | return (radians * 180.0) / M_PI; |
| | | } |
| | | |
| | | double round(double number, unsigned int bits) { |
| | | stringstream ss; |
| | | ss << setiosflags(ios::fixed) << setprecision(bits) << number; |
| | | ss >> number; |
| | | return number; |
| | | } |
| | | |
| | | void MakeLine(Line *line, const PointF *p1, const PointF *p2) |
| | |
| | | } |
| | | } |
| | | |
| | | // 0 - straight, 1 - left, -1 - right, 2 - front, -2 - back |
| | | int IntersectionOfLine(PointF p, Line line) |
| | | { |
| | | PointF p1, p2; |
| | |
| | | p2.X = line.X2; |
| | | p2.Y = line.Y2; |
| | | |
| | | IntersectionOfLine(p1, p2, p); |
| | | return IntersectionOfLine(p1, p2, p); |
| | | } |
| | | |
| | | /*************************************************************** |
| | |
| | | return false; |
| | | } |
| | | |
| | | bool VerticalPointOnLine(PointF point, Line line, PointF &vp) |
| | | { |
| | | PointF p1, p2; |
| | | |
| | | p1.X = line.X1; |
| | | p1.Y = line.Y1; |
| | | |
| | | p2.X = line.X2; |
| | | p2.Y = line.Y2; |
| | | |
| | | PointF pv = GetVerticalPoint(p1, p2, point); |
| | | |
| | | if (isEqual2(pv.X, MIN(p1.X, p2.X)) || isEqual2(pv.X, MAX(p1.X, p2.X)) || |
| | | (pv.X > MIN(p1.X, p2.X) && pv.X < MAX(p1.X, p2.X))) { |
| | | vp = pv; |
| | | return true; |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | /**************************************************************** |
| | | * p3 |
| | | * | 'L' |
| | |
| | | inline double toDegree(double radians); |
| | | inline bool isEqual(double a, double b); |
| | | inline bool isEqual2(double a, double b); |
| | | double round(double number, unsigned int bits); |
| | | |
| | | void MakeLine(Line *line, const PointF *p1, const PointF *p2); |
| | | void MakePolygon(Polygon *polygon, std::initializer_list<PointF> point_set); |
| | |
| | | int IntersectionOfLine(PointF p, Line line); |
| | | PointF GetVerticalPoint(PointF p1, PointF p2, PointF p3); |
| | | bool VerticalPointOnLine(PointF point, Line line); |
| | | bool VerticalPointOnLine(PointF point, Line line, PointF &vp); |
| | | PointF Calc3Point(PointF p1, PointF p2, double L, char dir); |
| | | PointF PointExtend(PointF ori, double length, double yaw); |
| | | #endif //GUI_GEOMETRY_H |
| | |
| | | |
| | | #include <vector> |
| | | #include <list> |
| | | #include <map> |
| | | #include <string> |
| | | #include <cstdlib> |
| | | |
| | |
| | | static const int TURN_CHECK_INTERVAL = 500; |
| | | const double SLIDE_DISTANCE_THRESHOLD_RED = 0.3; |
| | | const double SLIDE_DISTANCE_THRESHOLD_YELLOW = 0.1; |
| | | |
| | | static const int FIND_POSITION = -2; |
| | | static const int INVALID_POSITION = -1; |
| | | |
| | | static bool occurCrashRedLine; |
| | | static bool occurCrashGreenLine; |
| | |
| | | static bool handBreakActive = false; |
| | | static bool reportRPMOver = false; |
| | | |
| | | static int currCarOnRoadIndex; |
| | | |
| | | static const uint32_t TURN_ERROR_COLD_TIME = D_SEC(10); |
| | | |
| | | static bool turnError13Cold, turnError14Cold; |
| | | static struct car_on_lane { |
| | | int road; |
| | | int separate; |
| | | int lane; |
| | | } CarOnLane; |
| | | |
| | | static const int MAX_ENGINE_RPM = 2500; |
| | | static const double START_CAR_MOVE_DISTANCE = 10.0; |
| | |
| | | static const uint32_t CRASH_DOTTED_LINE_TIMEOUT = D_SEC(10); |
| | | static const uint32_t TURN_SIGNAL_LAMP_ADVANCE = D_SEC(3); |
| | | |
| | | static const int CRL_NONE = 0; |
| | | static const int CRL_SEP_DOTTED = 1; |
| | | static const int CRL_SEP_SOLID = 2; |
| | | static const int CRL_EDGE_DOTTED = 3; |
| | | static const int CRL_EDGE_SOLID = 4; |
| | | |
| | | static const double MAX_SPEED = 40.0 * 1000.0 / 3600.0; |
| | | static const int SPEED_GEAR_TABLE[][2] = {{0, 20}, {5, 30}, {15, 40}, {25, 10000}, {35, 10000}}; |
| | | |
| | | static void TestRoadStartCar(const car_model *car, double speed, int moveDirect, const struct RtkTime *rtkTime); |
| | | static int TestRoadStartCar(const car_model *car, double speed, int moveDirect, const struct RtkTime *rtkTime); |
| | | |
| | | static char isTurn(int currYaw, int prevYaw, int &ang); |
| | | static char CheckCarTurn(LIST_CAR_MODEL &CarModelList); |
| | |
| | | static void TurnSignalError13ColdTimer(union sigval sig); |
| | | static void TurnSignalError14ColdTimer(union sigval sig); |
| | | static void ReportTurnSignalError(int err, const struct RtkTime *rtkTime); |
| | | static bool UpdateLane(struct car_on_lane &out, road_t &road, const car_model *car); |
| | | static int CrashRoadLine(road_t &road, const car_model *car); |
| | | static bool LaneIsSame(struct car_on_lane lane1, struct car_on_lane lane2); |
| | | static bool LaneIsValid(struct car_on_lane lane); |
| | | |
| | | void InitRoadExam(void) |
| | | void InitRoadExam(road_exam_map &RoadMap) |
| | | { |
| | | DEBUG("Start road_exam"); |
| | | |
| | |
| | | prevGearNSlide = false; |
| | | gearNSlideTime = 0; |
| | | |
| | | currExamMapIndex = -1; |
| | | currExamMapIndex = FIND_POSITION; |
| | | |
| | | startCar = START_CAR_NOT_DO; |
| | | |
| | |
| | | checkStartCarSignal = startCarLeftTurnSignal = false; |
| | | |
| | | turnError13Cold = turnError14Cold = true; |
| | | |
| | | currCarOnRoadIndex = FIND_POSITION; |
| | | |
| | | CarOnLane.road = CarOnLane.separate = CarOnLane.lane = -1; |
| | | |
| | | InitThroughSomething(RoadMap); |
| | | } |
| | | |
| | | void TerminateRoadExam(void) |
| | |
| | | } |
| | | } |
| | | |
| | | static void TestRoadStartCar(const car_model *car, double speed, int moveDirect, const struct RtkTime *rtkTime) |
| | | static int TestRoadStartCar(const car_model *car, double speed, int moveDirect, const struct RtkTime *rtkTime) |
| | | { |
| | | double moveDistance; |
| | | |
| | |
| | | } else { |
| | | |
| | | } |
| | | |
| | | return startCar; |
| | | } |
| | | |
| | | void TestRoadGeneral(road_exam_map &RoadMap, const car_model *car, LIST_CAR_MODEL &CarModelList, double speed, int moveDirect, const struct RtkTime *rtkTime) |
| | | { |
| | | // 起步检测 |
| | | TestRoadStartCar(car, speed, moveDirect, rtkTime); |
| | | |
| | | // 超速检测 |
| | | if (moveDirect != 0 && speed > MAX_SPEED) { |
| | | if (!occurOverSpeed) { |
| | | occurOverSpeed = true; |
| | | // 超速,不合格 |
| | | AddExamFault(10, rtkTime); |
| | | } |
| | | } else { |
| | | occurOverSpeed = false; |
| | | } |
| | | |
| | | // 副刹车检测 |
| | | if (ReadCarStatus(SECOND_BREAK) == BREAK_ACTIVE) { |
| | | // 副刹车踩下,不合格 |
| | | if (!occurSecondBreak) { |
| | | DEBUG("副刹车动作了"); |
| | | occurSecondBreak = true; |
| | | AddExamFault(17, rtkTime); |
| | | } |
| | | } else { |
| | | occurSecondBreak = false; |
| | | } |
| | | |
| | | // 挡位匹配检测 |
| | | bool currGearError = false; |
| | | bool currGearNSlide = false; |
| | | |
| | | switch (ReadCarStatus(GEAR)) { |
| | | case GEAR_N: |
| | | if (moveDirect != 0) { |
| | | // 空档滑行 |
| | | currGearNSlide = true; |
| | | } |
| | | break; |
| | | case GEAR_1: |
| | | if (ConvertMs2KMh(speed) < SPEED_GEAR_TABLE[0][0] || ConvertMs2KMh(speed) > SPEED_GEAR_TABLE[0][1]) { |
| | | currGearError = true; |
| | | } |
| | | break; |
| | | case GEAR_2: |
| | | if (ConvertMs2KMh(speed) < SPEED_GEAR_TABLE[1][0] || ConvertMs2KMh(speed) > SPEED_GEAR_TABLE[1][1]) { |
| | | currGearError = true; |
| | | } |
| | | break; |
| | | case GEAR_3: |
| | | if (ConvertMs2KMh(speed) < SPEED_GEAR_TABLE[2][0] || ConvertMs2KMh(speed) > SPEED_GEAR_TABLE[2][1]) { |
| | | currGearError = true; |
| | | } |
| | | break; |
| | | case GEAR_4: |
| | | if (ConvertMs2KMh(speed) < SPEED_GEAR_TABLE[3][0] || ConvertMs2KMh(speed) > SPEED_GEAR_TABLE[3][1]) { |
| | | currGearError = true; |
| | | } |
| | | break; |
| | | case GEAR_5: |
| | | if (ConvertMs2KMh(speed) < SPEED_GEAR_TABLE[4][0] || ConvertMs2KMh(speed) > SPEED_GEAR_TABLE[4][1]) { |
| | | currGearError = true; |
| | | } |
| | | break; |
| | | default:break; |
| | | } |
| | | // 空档滑行超时 |
| | | if (currGearNSlide && prevGearNSlide) { |
| | | gearNSlideTime += TimeGetDiff(rtkTime->hh, rtkTime->mm, rtkTime->ss, rtkTime->mss*10, |
| | | gearNSlideTimePoint.hour, gearNSlideTimePoint.min, gearNSlideTimePoint.sec, gearNSlideTimePoint.msec*10); |
| | | } |
| | | if (gearNSlideTime > GEAR_N_SLIDE_TIMEOUT) { |
| | | // 空档滑行超5秒,不合格 |
| | | DEBUG("挡位滑行,超过5秒"); |
| | | AddExamFault(8, rtkTime); |
| | | gearNSlideTime = 0; |
| | | } |
| | | |
| | | prevGearNSlide = currGearNSlide; |
| | | if (prevGearNSlide) { |
| | | Rtk2DriveTimer(gearNSlideTimePoint, rtkTime); |
| | | } else { |
| | | gearNSlideTime = 0; |
| | | } |
| | | // 挡位不匹配超时 |
| | | if (currGearError && prevGearError) { |
| | | gearErrorTime += TimeGetDiff(rtkTime->hh, rtkTime->mm, rtkTime->ss, rtkTime->mss*10, |
| | | gearErrorTimePoint.hour, gearErrorTimePoint.min, gearErrorTimePoint.sec, gearErrorTimePoint.msec*10); |
| | | } |
| | | if (gearErrorTime > GEAR_ERROR_TIMEOUT) { |
| | | // 累计15秒,挡位-车速不匹配,不合格 |
| | | DEBUG("挡位错误超过15秒"); |
| | | AddExamFault(6, rtkTime); |
| | | gearErrorTime = 0; |
| | | } |
| | | |
| | | prevGearError = currGearError; |
| | | if (prevGearError) { |
| | | Rtk2DriveTimer(gearErrorTimePoint, rtkTime); |
| | | } |
| | | |
| | | // 起步后滑 |
| | | if (moveDirect != prevMoveDirect) { |
| | | if (moveDirect == 0) { |
| | | stopTimepoint = TimeMakeComposite(rtkTime->hh, rtkTime->mm, rtkTime->ss, rtkTime->mss*10); |
| | | reportStopCarOnRedArea = false; |
| | | |
| | | DEBUG("停车了 %d %d %d %d %d %d %d", rtkTime->YY, rtkTime->MM, rtkTime->DD, rtkTime->hh, rtkTime->mm, rtkTime->ss, rtkTime->mss); |
| | | } else if (moveDirect == -1 && prevMoveDirect == 0) { |
| | | DEBUG("开始后滑"); |
| | | stopPoint = car->basePoint; |
| | | occurSlide = true; |
| | | } |
| | | prevMoveDirect = moveDirect; |
| | | } else if (moveDirect == 0) { |
| | | uint32_t tp = TimeMakeComposite(rtkTime->hh, rtkTime->mm, rtkTime->ss, rtkTime->mss*10); |
| | | |
| | | /*if (tp - stopTimepoint >= STOP_CAR_TIME && !reportStopCarOnRedArea && CrashRedArea(RoadMapList, car)) { |
| | | // 停车超2秒,停在红区,不合格 |
| | | AddExamFault(16, rtkTime); |
| | | DEBUG("禁停区停车"); |
| | | reportStopCarOnRedArea = true; |
| | | }*/ |
| | | } else if (moveDirect == -1) { |
| | | if (occurSlide) { |
| | | double slideDistance = DistanceOf(stopPoint, car->basePoint); |
| | | |
| | | if (slideDistance > SLIDE_DISTANCE_THRESHOLD_YELLOW) { |
| | | slideNormalDistance = true; |
| | | } |
| | | |
| | | if (slideDistance > SLIDE_DISTANCE_THRESHOLD_RED && !slideLongDistance) { |
| | | // 后滑超过30厘米, 不合格 |
| | | AddExamFault(5, rtkTime); |
| | | DEBUG("后滑超过30厘米"); |
| | | slideLongDistance = true; |
| | | } |
| | | } |
| | | } else { |
| | | if (slideNormalDistance) { |
| | | // 后滑,扣10分 |
| | | AddExamFault(18, rtkTime); |
| | | DEBUG("后滑超过10厘米, 但不超过30厘米"); |
| | | } |
| | | |
| | | slideNormalDistance = false; |
| | | slideLongDistance = false; |
| | | occurSlide = false; |
| | | } |
| | | |
| | | // 检测通过路口、人行道等区域时,释放刹车或减速 |
| | | CheckBreakActive(RoadMap, car, CarModelList); |
| | | |
| | | // 检测离开此路段,全车需不在范围内 |
| | | if (currExamMapIndex >= 0) { |
| | | Polygon area; |
| | | int n = 0; |
| | | |
| | | area.num = 0; |
| | | |
| | | for (int j = 0; j < RoadMap.roads[currExamMapIndex].leftEdge.size(); ++j) { |
| | | if (j > 0) { |
| | | area.num += RoadMap.roads[currExamMapIndex].leftEdge[j].points.size() - 1; |
| | | } else { |
| | | area.num += RoadMap.roads[currExamMapIndex].leftEdge[j].points.size(); |
| | | } |
| | | } |
| | | for (int j = 0; j < RoadMap.roads[currExamMapIndex].rightEdge.size(); ++j) { |
| | | if (j > 0) { |
| | | area.num += RoadMap.roads[currExamMapIndex].rightEdge[j].points.size() - 1; |
| | | } else { |
| | | area.num += RoadMap.roads[currExamMapIndex].rightEdge[j].points.size(); |
| | | } |
| | | } |
| | | |
| | | area.point = (PointF *) malloc(area.num * sizeof(PointF)); |
| | | |
| | | for (int j = 0; j < RoadMap.roads[currExamMapIndex].leftEdge.size(); ++j) { |
| | | for (int k = (j>0?1:0); k < RoadMap.roads[currExamMapIndex].leftEdge[j].points.size(); ++k) { |
| | | area.point[n++] = RoadMap.roads[currExamMapIndex].leftEdge[j].points[k]; |
| | | } |
| | | } |
| | | |
| | | for (int j = RoadMap.roads[currExamMapIndex].rightEdge.size() - 1; j >= 0; --j) { |
| | | if (j == RoadMap.roads[currExamMapIndex].rightEdge.size() - 1) { |
| | | for (int k = RoadMap.roads[currExamMapIndex].rightEdge[j].points.size() - 1; k >= 0; --k) { |
| | | area.point[n++] = RoadMap.roads[currExamMapIndex].rightEdge[j].points[k]; |
| | | } |
| | | } else { |
| | | for (int k = RoadMap.roads[currExamMapIndex].rightEdge[j].points.size() - 2; k >= 0; --k) { |
| | | area.point[n++] = RoadMap.roads[currExamMapIndex].rightEdge[j].points[k]; |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 全车都需不在地图中 |
| | | Polygon carBody; |
| | | |
| | | carBody.num = car->bodyNum; |
| | | carBody.point = (PointF *)malloc(carBody.num * sizeof(PointF)); |
| | | for (int i = 0; i < carBody.num; ++i) { |
| | | carBody.point[i] = car->carXY[car->body[i]]; |
| | | } |
| | | |
| | | if (IntersectionOf(&carBody, &area) == GM_None) { |
| | | DEBUG("离开路段 id = %d", RoadMap.roads[currExamMapIndex].id); |
| | | currExamMapIndex = FIND_POSITION; |
| | | } |
| | | |
| | | free(carBody.point); |
| | | free(area.point); |
| | | } |
| | | if (currExamMapIndex == FIND_POSITION) { |
| | | for (int i = 0; i < RoadMap.roads.size(); ++i) { |
| | | Polygon area; |
| | | int n = 0; |
| | | |
| | | area.num = 0; |
| | | |
| | | for (int j = 0; j < RoadMap.roads[i].leftEdge.size(); ++j) { |
| | | if (j > 0) { |
| | | area.num += RoadMap.roads[i].leftEdge[j].points.size() - 1; |
| | | } else { |
| | | area.num += RoadMap.roads[i].leftEdge[j].points.size(); |
| | | } |
| | | } |
| | | for (int j = 0; j < RoadMap.roads[i].rightEdge.size(); ++j) { |
| | | if (j > 0) { |
| | | area.num += RoadMap.roads[i].rightEdge[j].points.size() - 1; |
| | | } else { |
| | | area.num += RoadMap.roads[i].rightEdge[j].points.size(); |
| | | } |
| | | } |
| | | |
| | | area.point = (PointF *) malloc(area.num * sizeof(PointF)); |
| | | |
| | | for (int j = 0; j < RoadMap.roads[i].leftEdge.size(); ++j) { |
| | | for (int k = (j>0?1:0); k < RoadMap.roads[i].leftEdge[j].points.size(); ++k) { |
| | | area.point[n++] = RoadMap.roads[i].leftEdge[j].points[k]; |
| | | } |
| | | } |
| | | |
| | | for (int j = RoadMap.roads[i].rightEdge.size() - 1; j >= 0; --j) { |
| | | if (j == RoadMap.roads[i].rightEdge.size() - 1) { |
| | | for (int k = RoadMap.roads[i].rightEdge[j].points.size() - 1; k >= 0; --k) { |
| | | area.point[n++] = RoadMap.roads[i].rightEdge[j].points[k]; |
| | | } |
| | | } else { |
| | | for (int k = RoadMap.roads[i].rightEdge[j].points.size() - 2; k >= 0; --k) { |
| | | area.point[n++] = RoadMap.roads[i].rightEdge[j].points[k]; |
| | | } |
| | | } |
| | | } |
| | | |
| | | if (IntersectionOf(car->carXY[car->axial[AXIAL_FRONT]], &area) == GM_Containment) { |
| | | currExamMapIndex = i; |
| | | DEBUG("进入道路 id = %d", RoadMap.roads[i].id); |
| | | break; |
| | | } |
| | | |
| | | free(area.point); |
| | | } |
| | | if (currExamMapIndex < 0) { |
| | | currExamMapIndex = INVALID_POSITION; |
| | | DEBUG("搜寻未果"); |
| | | } |
| | | } else if (currExamMapIndex == INVALID_POSITION) { |
| | | for (int i = 0; i < RoadMap.roads.size(); ++i) { |
| | | if (CrashTheLine(RoadMap.roads[i].startLine, car, CarModelList)) { |
| | | currExamMapIndex = i; |
| | | DEBUG("进入道路 id = %d", RoadMap.roads[i].id); |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | |
| | | if (currExamMapIndex >= 0) { |
| | | int crl = CrashRoadLine(RoadMap.roads[currExamMapIndex], car); |
| | | |
| | | if (crl == CRL_NONE) { |
| | | DEBUG("什么都没压"); |
| | | } else if (crl == CRL_SEP_DOTTED) { |
| | | DEBUG("压分道虚线"); |
| | | } else if (crl == CRL_SEP_SOLID) { |
| | | DEBUG("压分道实线"); |
| | | } else if (crl == CRL_EDGE_DOTTED) { |
| | | DEBUG("压边沿虚线"); |
| | | } else if (crl == CRL_EDGE_SOLID) { |
| | | DEBUG("压边沿实线"); |
| | | } |
| | | |
| | | if (crl != CRL_SEP_DOTTED || crl != CRL_SEP_SOLID) { |
| | | struct car_on_lane lane; |
| | | UpdateLane(lane, RoadMap.roads[currExamMapIndex], car); |
| | | if (!LaneIsSame(lane, CarOnLane)) { |
| | | if (LaneIsValid(CarOnLane)) { |
| | | // 车道变换 |
| | | DEBUG("变更车道"); |
| | | } |
| | | CarOnLane = lane; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | /************************************************************* |
| | | * 检测当前车道,以车头中点为基准 |
| | | * @param road |
| | | * @param car |
| | | */ |
| | | static bool UpdateLane(struct car_on_lane &out, road_t &road, const car_model *car) |
| | | { |
| | | bool leftExt = false, rightExt = false; |
| | | Line leftExtLine, rightExtLine; |
| | | struct car_on_lane lane; |
| | | |
| | | for (int i = 0; i < road.leftEdge.size(); ++i) { |
| | | PointF p1, p2; |
| | | Line edge; |
| | | |
| | | p1 = road.leftEdge[i].points[0]; |
| | | for (int j = 1; j < road.leftEdge[i].points.size(); ++j) { |
| | | p2 = road.leftEdge[i].points[j]; |
| | | MakeLine(&edge, &p1, &p2); |
| | | |
| | | PointF vp; |
| | | if (VerticalPointOnLine(car->carXY[car->axial[AXIAL_FRONT]], edge, vp)) { |
| | | leftExt = true; |
| | | MakeLine(&leftExtLine, &car->carXY[car->axial[AXIAL_FRONT]], &vp); |
| | | goto LEFT_EXT_CMP; |
| | | } |
| | | p1 = p2; |
| | | } |
| | | } |
| | | LEFT_EXT_CMP: |
| | | for (int i = 0; i < road.rightEdge.size(); ++i) { |
| | | PointF p1, p2; |
| | | Line edge; |
| | | |
| | | p1 = road.rightEdge[i].points[0]; |
| | | for (int j = 1; j < road.rightEdge[i].points.size(); ++j) { |
| | | p2 = road.rightEdge[i].points[j]; |
| | | MakeLine(&edge, &p1, &p2); |
| | | |
| | | PointF vp; |
| | | if (VerticalPointOnLine(car->carXY[car->axial[AXIAL_FRONT]], edge, vp)) { |
| | | rightExt = true; |
| | | MakeLine(&rightExtLine, &car->carXY[car->axial[AXIAL_FRONT]], &vp); |
| | | goto RIGHT_EXT_CMP; |
| | | } |
| | | p1 = p2; |
| | | } |
| | | } |
| | | RIGHT_EXT_CMP: |
| | | |
| | | if (!leftExt || !rightExt) { |
| | | return false; |
| | | } |
| | | |
| | | bool orthogonalInSegment = false; |
| | | |
| | | for (int i = 0; i < road.separate.size(); ++i) { // 段 |
| | | PointF p1, p2; |
| | | Line sep; |
| | | |
| | | map<int, int> orthogonal; |
| | | |
| | | // 一段分道组内,有一条正交,就必须保证同组的全都正交,否则直接退出 |
| | | for (int j = 0; j < road.separate[i].lines.size(); ++j) { // 线组 |
| | | bool intersection = false; |
| | | |
| | | for (int k = 0; !intersection && k < road.separate[i].lines[j].size(); ++k) { // 节 |
| | | |
| | | p1 = road.separate[i].lines[j][k].points[0]; |
| | | for (int m = 1; m < road.separate[i].lines[j][k].points.size(); ++m) { |
| | | p2 = road.separate[i].lines[j][k].points[m]; |
| | | MakeLine(&sep, &p1, &p2); |
| | | |
| | | if (IntersectionOf(leftExtLine, sep) == GM_Intersection) { |
| | | orthogonal.insert(pair<int, int>(j, 1)); |
| | | orthogonalInSegment = true; |
| | | intersection = true; |
| | | DEBUG("分道线 %d 左正交", j); |
| | | break; |
| | | } else if (IntersectionOf(rightExtLine, sep) == GM_Intersection) { |
| | | orthogonal.insert(pair<int, int>(j, 2)); |
| | | orthogonalInSegment = true; |
| | | intersection = true; |
| | | DEBUG("分道线 %d 右正交", j); |
| | | break; |
| | | } |
| | | p1 = p2; |
| | | } |
| | | } |
| | | } |
| | | DEBUG("目标 %d 当前 %d", road.separate[i].lines.size(), orthogonal.size()); |
| | | |
| | | if (orthogonal.size() > 0) { |
| | | if (orthogonal.size() == road.separate[i].lines.size()) { |
| | | // 得到当前在第几个车道 |
| | | int x = 0; |
| | | for (x = 0; x < orthogonal.size(); ++x) { |
| | | auto itx = orthogonal.find(x); |
| | | if (itx != orthogonal.end()) { |
| | | if (itx->second != 1) { |
| | | lane.road = road.id; |
| | | lane.separate = i; |
| | | lane.lane = itx->first; |
| | | |
| | | DEBUG("路 %d 段 %d 车道 %d", lane.road, lane.separate, lane.lane); |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | if (x >= orthogonal.size()) { |
| | | lane.road = road.id; |
| | | lane.separate = i; |
| | | lane.lane = orthogonal.size(); |
| | | |
| | | DEBUG("路 %d 段 %d 车道 %d", lane.road, lane.separate, lane.lane); |
| | | } |
| | | out = lane; |
| | | return true; |
| | | } else { |
| | | // 不完全正交,直接退出 |
| | | } |
| | | return false; |
| | | } |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | /************************************************************************* |
| | | * 碰触车道线型 |
| | | * @param road |
| | | * @param car |
| | | */ |
| | | static int CrashRoadLine(road_t &road, const car_model *car) |
| | | { |
| | | Line frontAxle, rearAxle; |
| | | |
| | | MakeLine(&frontAxle, &car->carXY[car->left_front_tire[TIRE_OUTSIDE]], &car->carXY[car->right_front_tire[TIRE_OUTSIDE]]); |
| | | MakeLine(&rearAxle, &car->carXY[car->left_rear_tire[TIRE_OUTSIDE]], &car->carXY[car->right_rear_tire[TIRE_OUTSIDE]]); |
| | | |
| | | // 检查道路边缘 |
| | | for (int i = 0; i < road.leftEdge.size(); ++i) { |
| | | PointF p1, p2; |
| | | Line edge; |
| | | |
| | | p1 = road.leftEdge[i].points[0]; |
| | | for (int j = 1; j < road.leftEdge[i].points.size(); ++j) { |
| | | p2 = road.leftEdge[i].points[j]; |
| | | MakeLine(&edge, &p1, &p2); |
| | | |
| | | if (IntersectionOf(edge, frontAxle) == GM_Intersection || |
| | | IntersectionOf(edge, rearAxle) == GM_Intersection) { |
| | | // 压道路左边线 |
| | | if (road.leftEdge[i].character != LINE_SOLID) { |
| | | return CRL_EDGE_DOTTED; |
| | | } |
| | | return CRL_EDGE_SOLID; |
| | | } |
| | | p1 = p2; |
| | | } |
| | | } |
| | | |
| | | for (int i = 0; i < road.rightEdge.size(); ++i) { |
| | | PointF p1, p2; |
| | | Line edge; |
| | | |
| | | p1 = road.rightEdge[i].points[0]; |
| | | for (int j = 1; j < road.rightEdge[i].points.size(); ++j) { |
| | | p2 = road.rightEdge[i].points[j]; |
| | | MakeLine(&edge, &p1, &p2); |
| | | |
| | | if (IntersectionOf(edge, frontAxle) == GM_Intersection || |
| | | IntersectionOf(edge, rearAxle) == GM_Intersection) { |
| | | // 压道路右边线 |
| | | if (road.rightEdge[i].character != LINE_SOLID) { |
| | | return CRL_EDGE_DOTTED; |
| | | } |
| | | return CRL_EDGE_SOLID; |
| | | } |
| | | p1 = p2; |
| | | } |
| | | } |
| | | |
| | | // 检查分道线 |
| | | for (int i = 0; i < road.separate.size(); ++i) { |
| | | // 段 |
| | | PointF p1, p2; |
| | | Line sep; |
| | | |
| | | for (int j = 0; j < road.separate[i].lines.size(); ++j) { |
| | | // 线 |
| | | for (int k = 0; k < road.separate[i].lines[j].size(); ++k) { |
| | | // 节 |
| | | p1 = road.separate[i].lines[j][k].points[0]; |
| | | |
| | | for (int m = 1; m < road.separate[i].lines[j][k].points.size(); ++m) { |
| | | p2 = road.separate[i].lines[j][k].points[m]; |
| | | MakeLine(&sep, &p1, &p2); |
| | | |
| | | if (IntersectionOf(sep, frontAxle) == GM_Intersection || |
| | | IntersectionOf(sep, rearAxle) == GM_Intersection) { |
| | | // 检查道路分隔线类型 |
| | | if (road.separate[i].lines[j][k].character == LINE_DOTTED) { |
| | | // 压虚线 |
| | | return CRL_SEP_DOTTED; |
| | | } else if (road.separate[i].lines[j][k].character == LINE_SOLID) { |
| | | // 压实线 |
| | | return CRL_SEP_SOLID; |
| | | } else if (road.separate[i].lines[j][k].character == LINE_HALF_SOLID_LEFT) { |
| | | if (LaneIsValid(CarOnLane) && CarOnLane.lane <= j) { |
| | | return CRL_SEP_SOLID; |
| | | } |
| | | return CRL_SEP_DOTTED; |
| | | } else if (road.separate[i].lines[j][k].character == LINE_HALF_SOLID_RIGHT) { |
| | | if (LaneIsValid(CarOnLane) && CarOnLane.lane > j) { |
| | | return CRL_SEP_SOLID; |
| | | } |
| | | return CRL_SEP_DOTTED; |
| | | } |
| | | } |
| | | |
| | | p1 = p2; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | return CRL_NONE; |
| | | } |
| | | |
| | | static bool LaneIsSame(struct car_on_lane lane1, struct car_on_lane lane2) |
| | | { |
| | | if (lane1.road == lane2.road && lane1.separate == lane2.separate && lane1.lane == lane2.lane) { |
| | | return true; |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | static bool LaneIsValid(struct car_on_lane lane) |
| | | { |
| | | if (lane.road >= 0 && lane.separate >= 0 && lane.lane >= 0) { |
| | | return true; |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | void TestRoadGeneral(LIST_ROAD_MAP &RoadMapList, const car_model *car, LIST_CAR_MODEL &CarModelList, double speed, int moveDirect, const struct RtkTime *rtkTime) |
| | |
| | | return map_idx; |
| | | } |
| | | |
| | | bool CrashTheLine(Line line, const car_model *car, LIST_CAR_MODEL &CarModelList) |
| | | { |
| | | if (CarModelList.size() < 2) |
| | | return false; |
| | | |
| | | list<car_model *>::iterator iter = CarModelList.begin(); |
| | | |
| | | Line trace; |
| | | PointF p1, p2; |
| | | |
| | | p1 = ((car_model *)(*iter))->carXY[((car_model *)(*iter))->axial[AXIAL_FRONT]]; |
| | | ++iter; |
| | | p2 = ((car_model *)(*iter))->carXY[((car_model *)(*iter))->axial[AXIAL_FRONT]]; |
| | | MakeLine(&trace, &p1, &p2); |
| | | |
| | | if (IntersectionOf(trace, line) == GM_Intersection && |
| | | IntersectionOfLine(p1, line) == -1) { |
| | | return true; |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | static int FindMapIndexById(int id, LIST_ROAD_MAP &RoadMapList) |
| | | { |
| | | for (int i = 0; i < RoadMapList.size(); ++i) { |
| | |
| | | return -1; |
| | | } |
| | | |
| | | #if 1 |
| | | /********************************************************************* |
| | | * 计算某点到道路左边线的最近垂点 |
| | | * @param edge |
| | | * @param road |
| | | * @param point |
| | | * @return |
| | | */ |
| | | PointF GetSELine(vector<edge_t> &edge, PointF point) |
| | | { |
| | | PointF p1, p2; |
| | | PointF px; |
| | | |
| | | vector<PointF> vps; |
| | | |
| | | Line line; |
| | | |
| | | for (int i = 0; i < edge.size(); ++i) { |
| | | p1 = edge[i].points[0]; |
| | | for (int j = 1; j < edge[i].points.size(); ++j) { |
| | | p2 = edge[i].points[j]; |
| | | MakeLine(&line, &p1, &p2); |
| | | |
| | | PointF vp; |
| | | if (VerticalPointOnLine(point, line, vp)) { |
| | | vps.push_back(vp); |
| | | } |
| | | |
| | | p1 = p2; |
| | | } |
| | | } |
| | | |
| | | if (vps.size() == 0) { |
| | | if (DistanceOf(point, edge[0].points[0]) < DistanceOf(point, edge[edge.size() - 1].points[edge[edge.size() - 1].points.size() - 1])) { |
| | | px = GetVerticalPoint(edge[0].points[0], edge[0].points[1], point); |
| | | } else { |
| | | px = GetVerticalPoint(edge[edge.size() - 1].points[edge[edge.size() - 1].points.size() - 2], edge[edge.size() - 1].points[edge[edge.size() - 1].points.size() - 1], point); |
| | | } |
| | | } else if (vps.size() == 1) { |
| | | px = vps[0]; |
| | | } else { |
| | | px = vps[0]; |
| | | for (int i = 1; i < vps.size(); ++i) { |
| | | if (DistanceOf(point, vps[i]) < DistanceOf(point, px)) { |
| | | px = vps[i]; |
| | | } |
| | | } |
| | | } |
| | | |
| | | return px; |
| | | } |
| | | |
| | | #if 0 |
| | | |
| | | typedef struct { |
| | | int road; |
| | | int segment; |
| | | int track; |
| | | int lane; |
| | | } CarOnTrackInfo_t; |
| | | |
| | | static CarOnTrackInfo_t CarOnTrackInfo; |
| | |
| | | |
| | | if (newCarOnTrackInfo.road == CarOnTrackInfo.road && |
| | | newCarOnTrackInfo.segment == CarOnTrackInfo.segment && |
| | | newCarOnTrackInfo.track != CarOnTrackInfo.track) { |
| | | newCarOnTrackInfo.lane != CarOnTrackInfo.lane) { |
| | | |
| | | } |
| | | |
| | |
| | | static void DetectSeparate(int currIndex, struct road_exam2_map &map, const car_model *car) |
| | | { |
| | | int segment; |
| | | int track = -1; |
| | | int lane = -1; |
| | | |
| | | CarOnTrackInfo_t newInfo; |
| | | |
| | |
| | | |
| | | vrecord.push_back(v); |
| | | |
| | | track = separate_line_num;// |
| | | lane = separate_line_num;// |
| | | } |
| | | |
| | | |
| | |
| | | if (rel != -1) { |
| | | newInfo.road = currIndex; |
| | | newInfo.segment = i; |
| | | newInfo.track = x; |
| | | newInfo.lane = x; |
| | | break; |
| | | } |
| | | } |
| | | |
| | | newInfo.road = currIndex; |
| | | newInfo.segment = i; |
| | | newInfo.track = vrecord.size(); |
| | | newInfo.lane = vrecord.size(); |
| | | |
| | | break; |
| | | } |
| | |
| | | }; |
| | | |
| | | void Rtk2DriveTimer(struct drive_timer &tm, const struct RtkTime *rtkTime); |
| | | void InitRoadExam(void); |
| | | void InitRoadExam(road_exam_map &RoadMap); |
| | | void TerminateRoadExam(void); |
| | | void TestRoadGeneral(road_exam_map &RoadMap, const car_model *car, LIST_CAR_MODEL &CarModelList, double speed, int moveDirect, const struct RtkTime *rtkTime); |
| | | void TestRoadGeneral(LIST_ROAD_MAP &RoadMapList, const car_model *car, LIST_CAR_MODEL &CarModelList, double speed, int moveDirect, const struct RtkTime *rtkTime); |
| | | bool ExitSonArea(int index, LIST_ROAD_MAP &RoadMapList, const car_model *car); |
| | | bool CrashSonRedLine(int index, LIST_ROAD_MAP &RoadMapList, const car_model *car, LIST_CAR_MODEL &CarModelList); |
| | | |
| | | bool CrashTheLine(Line line, const car_model *car, LIST_CAR_MODEL &CarModelList); |
| | | PointF GetSELine(std::vector<edge_t> &edge, PointF point); |
| | | |
| | | #endif //MYAPPLICATION2_ROAD_EXAM_H |
| | |
| | | // Created by YY on 2020/3/20. |
| | | // |
| | | |
| | | #include <map> |
| | | #include <algorithm> |
| | | |
| | | #include "through_something.h" |
| | | #include "../driver_test.h" |
| | | #include "../test_common/Geometry.h" |
| | |
| | | |
| | | #define DEBUG(fmt, args...) LOGD("<through_something> <%s>: " fmt, __func__, ##args) |
| | | |
| | | using namespace std; |
| | | |
| | | static const double LASTEST_BREAK_POINT = 30.0; |
| | | static const double DISTANCE_STOP_CAR_TO_STOP_LINE = 5.0; |
| | | static const double PASS_SCHOOL_MAX_SPEED = 30.0; // kmh |
| | | |
| | | static int breakActive; |
| | | static int stopActive; |
| | | static bool crashRedLine; |
| | | |
| | | static map<int, bool> breakRecord; // 记录车辆驶过各个停止线前刹车动作 |
| | | |
| | | void StartThroughExam(int index, LIST_ROAD_MAP &RoadMapList) |
| | | { |
| | |
| | | breakActive = 0; |
| | | stopActive = 0; |
| | | crashRedLine = false; |
| | | } |
| | | |
| | | void InitThroughSomething(road_exam_map &RoadMap) |
| | | { |
| | | breakRecord.clear(); |
| | | // 为每一个刹车检测点 |
| | | for (int i = 0; i < RoadMap.specialAreas.size(); ++i) { |
| | | if (RoadMap.specialAreas[i].type == ZEBRA_CROSSING || RoadMap.specialAreas[i].type == BUS_STATION_AREA) { |
| | | breakRecord.insert(pair<int, bool>(RoadMap.specialAreas[i].id, false)); |
| | | } |
| | | } |
| | | for (int i = 0; i < RoadMap.roads.size(); ++i) { |
| | | breakRecord.insert(pair<int, bool>(RoadMap.roads[i].id, false)); |
| | | } |
| | | } |
| | | |
| | | int ExecuteThroughExam(int index, LIST_ROAD_MAP &RoadMapList, const car_model *car, |
| | |
| | | return index; |
| | | } |
| | | |
| | | static void ThroughZebraCrossing(struct road_exam2_map &map, const car_model *car) |
| | | void CheckBreakActive(road_exam_map &map, const car_model *car, LIST_CAR_MODEL &CarModelList) |
| | | { |
| | | for (int i = 0; i < map.specialAreas.size(); i++) { |
| | | if (map.specialAreas[i].character == 'zebra') { |
| | | double distance = 0.0; |
| | | int BreakDone = ReadCarStatus(BREAK); |
| | | |
| | | for (int i = 0; i < map.specialAreas.size(); i++) { |
| | | if (map.specialAreas[i].type == ZEBRA_CROSSING || map.specialAreas[i].type == BUS_STATION_AREA) { |
| | | double yaw = YawOf(car->carXY[ car->axial[AXIAL_FRONT] ], car->carXY[ car->axial[AXIAL_REAR] ]); |
| | | PointF extPoint = PointExtend(car->carXY[ car->axial[AXIAL_FRONT] ], LASTEST_BREAK_POINT, yaw); |
| | | Line extLine; |
| | | MakeLine(&extLine, &car->carXY[ car->axial[AXIAL_FRONT] ], &extPoint); |
| | | |
| | | if (IntersectionOf(extLine, map.specialAreas[i].startLine) == GM_Intersection && |
| | | IntersectionOfLine(car->carXY[ car->axial[AXIAL_FRONT] ], map.specialAreas[i].startLine) == 1 ) { |
| | | jj = true; |
| | | if (ReadCarStatus(BREAK) == BREAK_ACTIVE) { |
| | | breakActive = 1; |
| | | } |
| | | } else { |
| | | jj = false; |
| | | // 计算点到左侧路边线的垂点 |
| | | int road = 0; |
| | | for (road = 0; road < map.roads.size(); ++road) { |
| | | if (map.roads[road].id == map.specialAreas[i].road) |
| | | break; |
| | | } |
| | | |
| | | PointF vPoint = GetSELine(map.roads[road].leftEdge, map.specialAreas[i].area[0]); |
| | | Line startLine; |
| | | |
| | | DEBUG("计算垂点 (%f, %f)", vPoint.X, vPoint.Y); |
| | | |
| | | MakeLine(&startLine, &map.specialAreas[i].area[0], &vPoint); |
| | | |
| | | |
| | | if (distance < LASTEST_BREAK_POINT) { |
| | | if (ReadCarStatus(BREAK) == BREAK_ACTIVE) { |
| | | breakActive = 1; |
| | | // 车头和斑马线距离不足30米 |
| | | if (IntersectionOf(extLine, startLine) == GM_Intersection && |
| | | IntersectionOfLine(car->carXY[ car->axial[AXIAL_FRONT] ], startLine) == 1 ) { |
| | | DEBUG("进入减速区"); |
| | | if (BreakDone == BREAK_ACTIVE) { |
| | | auto itx = breakRecord.find(map.specialAreas[i].id); |
| | | if (itx != breakRecord.end()) { |
| | | itx->second = true; |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 跨线后,检查刹车动作 |
| | | if (CrashTheLine(startLine, car, CarModelList)) { |
| | | auto itx = breakRecord.find(map.specialAreas[i].id); |
| | | if (itx != breakRecord.end()) { |
| | | if (itx->second == false) { |
| | | // 不按规定减速,不合格 |
| | | DEBUG("不按规定减速"); |
| | | } |
| | | itx->second = false; |
| | | } |
| | | } |
| | | } else if (map.specialAreas[i].type == SCHOOL_AREA) { |
| | | |
| | | } |
| | | } |
| | | } |
| | | |
| | |
| | | #include "../driver_test.h" |
| | | |
| | | void StartThroughExam(int index, LIST_ROAD_MAP &RoadMapList); |
| | | void InitThroughSomething(road_exam_map &RoadMap); |
| | | void CheckBreakActive(road_exam_map &map, const car_model *car, LIST_CAR_MODEL &CarModelList); |
| | | int ExecuteThroughExam(int index, LIST_ROAD_MAP &RoadMapList, const car_model *car, |
| | | LIST_CAR_MODEL &CarModelList, double speed, int moveDirect, const struct RtkTime *rtkTime); |
| | | |
| | |
| | | |
| | | new Thread(new TestThread()).start(); |
| | | |
| | | PlayRing(this); |
| | | // PlayRing(this); |
| | | } |
| | | |
| | | public void PlayRing(Context context) { |