车道类的数据有三部分:
一是车道自身属性,包括位置和方向信息:起点、终点(弯道还有弧线圆心点)和道路交通信息:限速速度等;
二是自身的标号索引,初步想了所在场景编号(用于表示所在场景之间的关系,可能今后在长路径规划时会用到)、场景内的车道编号(用于在场景内部车之间的变道和和掉头)、地图中的总车道号(在全局中可能有用)。
三是车辆下一步可能去到的车道索引(指针),包括平行车道ParaLane和下一车道NextLane,平行车道即可能变道和掉头的目标车道;下一车道表示正常向前行驶会去到的车道,对于直道、弯道、匝道入来说只有一个下一道,而对于路口、匝道出来说有多个下一道。
下面是Lane车道类的代码
“lane.h”:
#ifndef LANE_H
#define LANE_H
#include
#include
class Lane
{
public:
Lane(int indexScene, //构造函数
int indexLaneOfScene,
int indexLaneOfMap,
QPointF startPoint,
QPointF endPoint);
Lane(QPointF startPoint = QPointF(0,0), //临时写的构造函数,只有起点和终点
QPointF endPoint = QPointF(0,0));
void refreshPoints(QPointF startPoint, QPointF endPoint); //刷新标志点
void move(QPointF m); //移动
//private: //原本想写成私有成员,但是其他类里要调用不太方便,先注释掉,写成public的
int IndexScene; //所在场景编号
int IndexLaneOfScene; //场景内的车道编号
int IndexLaneOfMap; //地图中的总车道号
QList<Lane*> ParaLane; //平行车道
QList<Lane*> NextLane; //下一车道
QPointF StartPoint; //起始点
QPointF EndPoint; //终点
//QPoint CentrePoint; //中点,不知道当时咋想的
//int SpeedLimit; //限速
};
#endif // LANE_H
“lane.cpp”
#include "lane.h"
Lane::Lane(int indexScene,
int indexLaneOfScene,
int indexLaneOfMap,
QPointF startPoint,
QPointF endPoint)
{
IndexScene = indexScene; //场景号
IndexLaneOfScene = indexLaneOfScene; //场景内部的车道号
IndexLaneOfMap = indexLaneOfMap; //地图中的总车道号
StartPoint = startPoint; //起点
EndPoint = endPoint; //终点
}
Lane::Lane(QPointF startPoint, QPointF endPoint) //临时写的构造函数,只有起点终点两个值
{
StartPoint = startPoint;
EndPoint = endPoint;
}
void Lane::refreshPoints(QPointF startPoint, QPointF endPoint)
{
StartPoint = startPoint;
EndPoint = endPoint;
}
void Lane::move(QPointF m)
{
StartPoint += m;
EndPoint += m;
}
将接口处的车道存入接口类中,这样在接口对接时可以同时将两个场景的相邻车道进行连接。
在原来的接口类Interface中增加了用于存储本接口处的几条车道对象的QList
关于“接口类Interface”、“场景类Scenes”、“车道类Lane”对象在一张地图中的存储和调用形式:
1.一张地图有一个List对象:QListListScenes用于存储本地图中所有的场景,以链表List形式存储在地图中,有序号顺序,但这个序号本身没有任何含义,只是将本地图中所有的场景逐一保存下来。
2.每一个场景中用一个List“QListInterfaces”存储自己的所有接口,再用一个“QList AdjacentInterfaces”(还没写,没有仔细构思是否需要这个以及怎么用)来存储与自己相连的接口的指针。
3.每一个接口Interface中存有该接口处的几条车道的指针。
4.车道之间有一套自己的关系网(平行车道or下一车道),可以相互找到并调用。
Note:使用指针的特点在于所有记录的内容直接就是对应的对象,而非仅仅是登记在名册上的一个名字,所以所有操作都直接对相应对象进行。比如直道两端两个接口Interface对应的车道Lane其实是重复的,对一个接口里的车道操作其实同时也对另一端的接口里的车到进行了(他俩其实就是同一个东西。)
#ifndef INTERFACE_H
#define INTERFACE_H
#include
#include "lane.h"
class Interface
{
public:
Interface(QPointF FlagPoint = QPointF(0,0),
int Num_lanesGo = 0,
int Num_lanesBack = 0,
int Dir = 0);
void refreshAll(QPointF flagPoint);
void refresh(QPointF flagPoint, double wide_lane, int dir);
void refreshFlagPos(QPointF flagPoint);
//void refreshLanes(QPointF flagPoint);
public:
QPointF FlagPoint;
int Num_lanesGo;
int Num_lanesBack;
int Dir;
QList<Lane*> Lanes;
};
对应地,接口及车道初始化和接口录入部分的代码也进行了修改。目前仅修改了直道类stright.cpp中的接口录入部分,其他道路模块中的添加接口部分都需要修改,因此暂时将各模块中录入接口的部分注释掉了,所以目前除直道外不能进行自动吸附。
//初始化Interface和Lanes
QMatrix matrix; //变换矩阵
matrix.rotate(-Dir); //顺时针旋转-Dir°
Interfaces<<new Interface(QPointF(GlobalPos+QPointF(-Len_lane/2,0)*matrix), Num_laneR , Num_laneL , Dir)
<<new Interface(QPointF(GlobalPos+QPointF(Len_lane/2,0)*matrix), Num_laneL , Num_laneR , Dir+180);//>360 ? Dir-180 : Dir
int num_lanes = Num_laneL+Num_laneR;
double x0 = -Len_lane/2;
double y0 = -(Wid_lane*num_lanes/2 - Wid_lane/2);
QPointF startPoint;
QPointF endPoint;
for(int i=0; i<Num_laneL; ++i){
startPoint = QPointF(GlobalPos+QPointF(x0+Len_lane,y0+i*Wid_lane)*matrix);
endPoint = QPointF(GlobalPos+QPointF(x0,y0+i*Wid_lane)*matrix);
Interfaces.at(0)->Lanes<<new Lane(startPoint,endPoint);
}
double y = y0 + Wid_lane*Num_laneL;
for(int i=0; i<Num_laneR; ++i){
startPoint = QPointF(GlobalPos+QPointF(x0,y+i*Wid_lane)*matrix);
endPoint = QPointF(GlobalPos+QPointF(x0+Len_lane,y+i*Wid_lane)*matrix);
Interfaces.at(0)->Lanes<<new Lane(startPoint,endPoint);
}
for(int i=Interfaces.at(0)->Lanes.size()-1; i>=0; --i){
Interfaces.at(1)->Lanes<<Interfaces.at(0)->Lanes.at(i);
}
//qDebug()<<"初始车道点:"<Lanes.at(0)->StartPoint<Lanes.at(0)->EndPoint;
//刷新接口点
Interfaces.at(0)->refreshFlagPos(QPointF(GlobalPos+QPointF(-Len_lane/2,0)*matrix));
Interfaces.at(1)->refreshFlagPos(QPointF(GlobalPos+QPointF(Len_lane/2,0)*matrix));
qDebug()<<QPointF(GlobalPos+QPointF(-Len_lane/2,0)*matrix)
<<QPointF(GlobalPos+QPointF( Len_lane/2,0)*matrix);
//刷新车道中线对象
QPointF interfacePoint0 = Interfaces.at(0)->FlagPoint;
QPointF interfacePoint1 = Interfaces.at(1)->FlagPoint;
QPointF startPoint;
QPointF endPoint;
QPointF movement;
QPointF dMovement = QPointF(0,Wid_lane);
int i = 0;
if(num_lanes%2 == 1){ //车道数为奇数
movement = QPointF(0,-(num_lanes-1)/2*Wid_lane);
for(i=0; i<Num_laneL; ++i){
startPoint = (interfacePoint1 + movement*matrix);
endPoint = (interfacePoint0 + movement*matrix);
Interfaces.at(0)->Lanes.at(i)->refreshPoints(startPoint,endPoint);
movement += dMovement;
}
for(i=Num_laneL; i<num_lanes; ++i){
startPoint = (interfacePoint0 + movement*matrix);
endPoint = (interfacePoint1 + movement*matrix);
Interfaces.at(0)->Lanes.at(i)->refreshPoints(startPoint,endPoint);
movement += dMovement;
}
}
else{ //车道数为偶数
movement = QPointF(0,-(num_lanes/2-0.5)*Wid_lane);
for(i=0; i<Num_laneL; ++i){
startPoint = (interfacePoint1 + movement*matrix);
endPoint = (interfacePoint0 + movement*matrix);
Interfaces.at(0)->Lanes.at(i)->refreshPoints(startPoint,endPoint);
movement += dMovement;
}
for(i=Num_laneL; i<num_lanes; ++i){
startPoint = (interfacePoint0 + movement*matrix);
endPoint = (interfacePoint1 + movement*matrix);
Interfaces.at(0)->Lanes.at(i)->refreshPoints(startPoint,endPoint);
movement += dMovement;
}
}