这里使用roslaunch runtime_manager runtime_manager.launch运行autoware的过程就不讲了,网上有很多教程。
这篇博客可以学到两点:
1.通过界面设置导入轨迹。
2.通过阅读代码理解导入轨迹过程。
(1)先设置waypoint_loader中app中multi_lane中的数据文件,这里为下载数据包中的地址。
设置完,勾选就可以看见下图中的轨迹。
查看数据:
robert@robert-HP-ZBook-Firefly-14-G7-Mobile-Workstation:~$ rostopic echo /based/lane_waypoints_raw
ERROR: Cannot load message class for [autoware_msgs/LaneArray]. Are your messages built?
报错,这是由于autoware_msgs/LaneArray是自己定义的message数据类型,所以需要source一下工作空间。
cd autoeare.ai
source install/setup.bash
rostopic echo /based/lane_waypoints_raw
(2)这部分代码在core_planning/waypoint_maker/waypoint_loader中,
这个就是代码发布的话题:
void WaypointLoaderNode::initPubSub()
{
private_nh_.param<std::string>("multi_lane_csv", multi_lane_csv_, "/tmp/driving_lane.csv");
// setup publisher
lane_pub_ = nh_.advertise<autoware_msgs::LaneArray>("/based/lane_waypoints_raw", 10, true);
}
这里可以看到发布的话题为/based/lane_waypoints_raw。这就是上面打印数据的话题。
现在来看看代码的流程:
void WaypointLoaderNode::run()
{
multi_file_path_.clear();
parseColumns(multi_lane_csv_, &multi_file_path_);
autoware_msgs::LaneArray lane_array;
createLaneArray(multi_file_path_, &lane_array);
lane_pub_.publish(lane_array);
output_lane_array_ = lane_array;
ros::spin();
}
parseColumns的作用就是把输入的数据地址空格去掉。具体可以看下面这个代码,运行一下就知道作用了。
使用在线Codingground(https://www.tutorialspoint.com/compile_cpp_online.php)运行如下代码进行熟悉Autoware中的参数是怎么导入的,这是从代码中移植过来的。
#include <iostream>
#include <vector>
#include <sstream>
#include <algorithm>
#include <fstream>
using namespace std;
void parseColumns(const std::string line, std::vector<std::string>* columns)
{
std::istringstream ss(line);
std::string column;
while (std::getline(ss, column, ','))
{
while (1)
{
auto res = std::find(column.begin(), column.end(), ' ');
if (res == column.end())
{
break;
}
column.erase(res);
}
if (!column.empty())
{
columns->emplace_back(column);
}
}
}
bool verifyFileConsistency(const char* filename)
{
cout<<"verify..."<<endl;
std::ifstream ifs(filename);
if (!ifs)
{
return false;
}
return true;
}
int main(int argc, char **argv)
{
vector<string> multi_file_path_;
string multi_lane_csv_="/tmp/driving_lane.csv, /tmp/ driving_lane2.csv, /tmp/driving_lane3.csv";
multi_file_path_.clear();
cout<<"multi_file_path_.size()="<<multi_file_path_.size()<<endl;
parseColumns(multi_lane_csv_,&multi_file_path_);
int i=0;
for (const auto& el : multi_file_path_)
{
if (!verifyFileConsistency(el.c_str()))
{
cout<<"lane data is something wrong..."<<endl;
}
cout<<"lane data is valid. publishing..."<<endl;;
}
}
然后通过这个函数 createLaneArray(multi_file_path_, &lane_array)把车道数据写入lane_array
这个过程可以看到调用了verifyFileConsistency判断根据函数名,判断有效性。首先ifstream以输入方式打开文件filename,如果打开失败那么就直接返回false;如果成功打开此文件,则执行checkFileFormat函数。
通过checkFileFormat(file_path.c_str()判断文件的类型,这里头文件通过枚举设置了类型。然后根据类型通过loadWaypointsForVer1(file_path.c_str(), &wps)导入数据。
enum class FileFormat : int32_t
{
ver1, // x,y,z,(velocity)
ver2, // x,y,z,yaw,(velocity)
ver3, // first line consists on explanation of values
unknown = -1,
};
其中:
上面vert1, ver2, ver3类型图片来源于地址https://www.jianshu.com/p/1f091becac05。
void WaypointLoaderNode::createLaneArray(const std::vector<std::string>& paths, autoware_msgs::LaneArray* lane_array)
{
for (const auto& el : paths)
{
autoware_msgs::Lane lane;
createLaneWaypoint(el, &lane);
lane_array->lanes.emplace_back(lane);
}
}
oid WaypointLoaderNode::createLaneWaypoint(const std::string& file_path, autoware_msgs::Lane* lane)
{
if (!verifyFileConsistency(file_path.c_str()))
{
ROS_ERROR("lane data is something wrong...");
return;
}
ROS_INFO("lane data is valid. publishing...");
FileFormat format = checkFileFormat(file_path.c_str());
std::vector<autoware_msgs::Waypoint> wps;
if (format == FileFormat::ver1)
{
loadWaypointsForVer1(file_path.c_str(), &wps);
}
else if (format == FileFormat::ver2)
{
loadWaypointsForVer2(file_path.c_str(), &wps);
}
else
{
loadWaypointsForVer3(file_path.c_str(), &wps);
}
lane->header.frame_id = "/map";
lane->header.stamp = ros::Time(0);
lane->waypoints = wps;
}
3.也可以直接启动waypoint_loader.launch文件加载路径
首先要更改一下waypoint_loader.launch里面的内容,内容如下:
<!-- -->
<launch>
<arg name="load_csv" default="true" />
<!--<arg name="multi_lane_csv" default="/tmp/driving_lane.csv" />-->
<arg name="multi_lane_csv" default="/home/robert/.autoware/data/path/moriyama_path.txt" />
<!-- rosrun waypoint_maker waypoint_loader _multi_lane_csv:="path file" -->
<node pkg="waypoint_maker" type="waypoint_loader" name="waypoint_loader" output="screen" if="$(arg load_csv)">
<param name="multi_lane_csv" value="$(arg multi_lane_csv)" />
</node>
<node pkg="waypoint_maker" type="waypoint_replanner" name="waypoint_replanner" output="screen"/>
<node pkg="waypoint_maker" type="waypoint_marker_publisher" name="waypoint_marker_publisher" />
</launch>
更改的地方我已经标红色了,这样更改完以后编译一下,就可以启动launch文件,也可以打印出发布的/based/lane_waypoints_raw