1 | lsof abc.txt //显示开启文件abc.txt的进程 |
使用后发现对文本文件、图片这样的文件不适用,对可执行文件适用。
1 | lsof abc.txt //显示开启文件abc.txt的进程 |
使用后发现对文本文件、图片这样的文件不适用,对可执行文件适用。
最简单的平滑算法,处理A星路径。效果如下


均值平滑的使用不宜太多,如图map坐标系的Y轴正向是朝左的,红色路径最左边的点,经过3次均值平滑,肯定会朝右平移,造成平滑后的路径靠近了障碍物
1 | /** |
补充1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20vector<Point2D> samplePoints(const vector<Point2D>& input_points, int interval)
{
vector<Point2D> anchor_points;
int sampling_num = std::max(2, static_cast<int>(input_points.size() / interval + 0.5) );
vector<double> anchor_id;
Point2D temp_point;
uniform_slice(0, input_points.size(), sampling_num - 1, &anchor_id);
for(int i=0; i< anchor_id.size(); i++)
{
// cout << anchor_id.at(i) << " ";
temp_point = input_points.at(anchor_id.at(i) );
// cout << "anchor X: " << temp_point.first <<endl;
// cout << "anchor Y: " << temp_point.second <<endl;
anchor_points.push_back(temp_point);
}
return anchor_points;
}
1 | /** |
1 | PathPoint GetWeightedAverageOfTwoPathPoints(const PathPoint& p1, |
1 | // Test whether two float or double numbers are equal. |
测试的要求: 不能把地面加入costmap,但是稍高于地面的物体能加入。
不断调整 max_obstacle_height, min_obstacle_height, obstacle_range, raytrace_range 四个参数,但是costmap发现生成的障碍总是清除不掉。
换了另一个相机和雷达,发现没有这个问题. 后来发现有时甚至不能生成障碍了。
清除障碍的函数重点是ObservationBuffer::purgeStaleObservations()其中的 observation_list_,它又来自bufferCloud函数中的observation_cloud,后者又来自 global_frame_cloud。
相机发布的点云是在相机坐标系,在bufferCloud函数里用pcl_ros::transformPointCloud转换到代价地图的全局坐标系(也就是yaml中指定的global_frame,一般关注的是local costmap。) 得到 global_frame_cloud。然后按如下条件筛选出 observation_cloud1
2
3
4
5
6
7
8for (unsigned int i = 0; i < cloud_size; ++i)
{
if (global_frame_cloud.points[i].z <= max_obstacle_height_
&& global_frame_cloud.points[i].z >= min_obstacle_height_)
{
observation_cloud.points[point_count++] = global_frame_cloud.points[i];
}
}
因此 min_obstacle_height 和 max_obstacle_height是在代价地图全局坐标系下的值。
在bufferCloud函数中加入代码,把observation_cloud发布出来1
2
3sensor_msgs::PointCloud2 observation_ros_cloud;
pcl::toROSMsg(observation_cloud, observation_ros_cloud);
observation_cloud_pub.publish( observation_ros_cloud );
在构造函数里加入1
2
3ros::NodeHandle n;
n.param("publish_observation_cloud", pub_observation_cloud_, false );
observation_cloud_pub = n.advertise < sensor_msgs::PointCloud2 > ("observation_cloud", 2);
这样可以观察最终生成的障碍来自什么样的点云。比如下面两个点云的对比
最后查啊查啊,终于发现和其他相机的区别不在参数,而在于我之前修改相机驱动时的滤波,滤得太狠了。于是修改驱动,y和z方向的点云不能太少,终于可以清除成功了。
问题的根源在于滤波后的点太少而且稀疏, 导致raytrace机制不能清除障碍。 点云滤波不能直接滤到自己需要的范围,比如即使你实际需要1m的距离,驱动里也不能只给1m,竖直y方向也不能太小,体素滤波的体素不能太大,一般取0.01,这个对点云数量的影响也很大。
1 | std::vector<int> v; |
结果是 1 3 5 7 9
常见iterator自增,如果多增加,可能报错1
2
3
4
5
6
7
8
9
10
11
12std::vector<int> v;
v.push_back(0);
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);
for(vector<int>::iterator it=v.begin(); it != v.end(); it++)
{
it = it + 5;
cout << *it << endl;
}
这样的程序是错的,会越界。 应该改成这样1
2
3
4
5
6for(vector<int>::iterator it=v.begin(); it != v.end(); it++)
{
int step = v.end() - it;
it = it+step/5;
cout << *it << endl;
}
有一次机器人没有装雷达和相机,打算随便跑跑。于是在通用代价地图的障碍层,不设置传感器数据来源,运行move_base出现频繁报警1
The /scan observation buffer has not been updated for 22.06 seconds, and it should be updated every 5.00 seconds.
来源在1
2
3
4
5
6
7
8
9
10
11
12
13
14bool ObservationBuffer::isCurrent() const
{
if (expected_update_rate_ == ros::Duration(0.0))
return true;
// last_updated_ 没有赋值
bool current = (ros::Time::now() - last_updated_).toSec() <= expected_update_rate_.toSec();
if (!current)
{
ROS_WARN(
"The %s observation buffer has not been updated for %.2f seconds, and it should be updated every %.2f seconds.",
topic_name_.c_str(), (ros::Time::now() - last_updated_).toSec(), expected_update_rate_.toSec());
}
return current;
}
此时发导航命令,又有报警1
[/move_base]:Sensor data is out of date, we're not going to allow commanding of the base for safety
因为没有可靠的传感器数据,move_base不允许车跑起来。来源在MoveBase::executeCycle1
2
3
4
5
6if(!controller_costmap_ros_->isCurrent())
{
ROS_WARN("[%s]:Sensor data is out of date, we're not going to allow commanding of the base for safety",ros::this_node::getName().c_str());
publishZeroVelocity();
return false;
}
也就是函数1
2
3
4
5
6
7
8
9bool LayeredCostmap::isCurrent()
{
current_ = true;
for (vector<boost::shared_ptr<Layer> >::iterator plugin = plugins_.begin(); plugin != plugins_.end();
++plugin)
{
current_ = current_ && (*plugin)->isCurrent();
}
}
显然是因为障碍层不符合isCurrent,导致代价地图也不符合isCurrent。如果希望车照样跑,就把MoveBase::executeCycle那段注释掉,把ObservationBuffer::isCurrent()的报警也注释掉,否则没完没了。
从网上下载一个包含雷达数据的bag,又设置了通用代价地图和tf树后,发现报警依然,应该还是时间戳问题,懒得再对齐了。