vins-fusion+ego-planner在仿真小车上的部署

OK,现在我们尝试将vins-fusion与ego-planner相结合,来实现路径规划,因为小车算是二维运动的,所以我们直接用无人机的ego-planner算法,这里我使用了https://github.com/Forrest-Z/ego-planner-for-ground-robot,这个文件实现了把ego-planner部署到小车上。

跟着教程编译完之后,我们需要做以下几步:

参数更改:

这里我们修改plan_manage/run_in_sim.launch文件中的三个参数,

<arg name="cloud_topic" value="/your_cloud_topic"/>
<arg name="odom_topic" value="/your_odom_topic"/>
<arg name="goal_topic" value="/your_odom_topic"/>

替换成你自己的话题,第二个odom_topic即为vins-fusion发布的消息

<arg name="odom_topic" value="/vins_estimator/odometry" />
<arg name="cloud_topic" value="/depth_camera/depth/points"/>
<arg name="goal_topic" value="/move_base_simple/goal"/>

哦对了,忘了说了,点云消息需要深度相机,之前跟着赵虚左老师过了一遍的话正好有一个kinect深度相机,使用的时候记得加上。

消息类型转换

改完之后,我们打开ego-planner下的traj_server.cpp文件,

ros::Publisher vel_cmd_pub;

//quadrotor_msgs::PositionCommand cmd;
geometry_msgs::TwistStamped cmd;

从前几行我们可以发现,话题发布的名称是 vel_cmd_pub,类型是TwistStamp,可是我们小车需要Twist类型的消息,这就意味着我们需要对发布的话题类型做一下转换,代码如下:

#!/usr/bin/env python3

import rospy
from geometry_msgs.msg import TwistStamped, Twist

def twist_stamped_callback(msg):
    # Extract Twist from TwistStamped message
    twist = msg.twist
    # Publish the extracted Twist message
    twist_pub.publish(twist)

if __name__ == '__main__':
    rospy.init_node('twist_stamped_to_twist_converter')
    twist_pub = rospy.Publisher('/cmd_vel/convert', Twist, queue_size=10)
    rospy.Subscriber('cmd_vel', TwistStamped, twist_stamped_callback)
    rospy.spin()

这里我们将TwistStamp类型的消息变更为了名称是“/cmd_vel/convert”,类型是Twist的消息,小车可以接受到路径规划的消息。

打开ego-planner后可以在rviz中规划,这是原文档里都有,我就不再赘述,如果你想发布自己的消息,可以创建一个发布端发布目标点的信息,如下所示:

#!/usr/bin/env python3

import rospy
from geometry_msgs.msg import PoseStamped

def send_goal():
    rospy.init_node('goal_publisher', anonymous=True)
    pub = rospy.Publisher('/move_base_simple/goal', PoseStamped, queue_size=10)
    rospy.sleep(1)  # Wait for publisher to register

    goal = PoseStamped()
    goal.header.stamp = rospy.Time.now()
    goal.header.frame_id = "map"
    goal.pose.position.x = 1.0
    goal.pose.position.y = 2.0
    goal.pose.orientation.w = 1.0

    pub.publish(goal)
    rospy.loginfo("Goal sent!")

if __name__ == '__main__':
      try:
        send_goal()
      except rospy.ROSInterruptException:
        pass

这里我随便写了一下,大家可以根据需要修改,还有一些参数的修改可以看文档,至此,我们成功实现仿真小车中的ego-planner+vins-fusion跑通

  • 11
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Ego-Planner是一个基于ROS的路径规划器,它可以在给定的地图和起点、终点信息下,生成一条可行的路径。以下是Ego-Planner的代码框架: 1. 首先需要定义一个EgoPlanner类,其中包含了一些必要的成员变量和函数。 ```c++ class EgoPlanner { private: ros::NodeHandle nh_; ros::Subscriber sub_map_; ros::Subscriber sub_pose_; ros::Subscriber sub_goal_; ros::Publisher pub_path_; nav_msgs::OccupancyGrid map_; geometry_msgs::PoseStamped start_; geometry_msgs::PoseStamped goal_; public: EgoPlanner(); // 构造函数 ~EgoPlanner(); // 析构函数 void mapCallback(const nav_msgs::OccupancyGrid::ConstPtr& msg); // 地图回调函数 void poseCallback(const geometry_msgs::PoseStamped::ConstPtr& msg); // 当前位置回调函数 void goalCallback(const geometry_msgs::PoseStamped::ConstPtr& msg); // 目标位置回调函数 void plan(); // 路径规划函数 }; ``` 2. 在构造函数中,需要完成ROS节点的初始化、订阅和发布话题的设置。 ```c++ EgoPlanner::EgoPlanner() { nh_ = ros::NodeHandle("~"); sub_map_ = nh_.subscribe("map", 1, &EgoPlanner::mapCallback, this); sub_pose_ = nh_.subscribe("pose", 1, &EgoPlanner::poseCallback, this); sub_goal_ = nh_.subscribe("goal", 1, &EgoPlanner::goalCallback, this); pub_path_ = nh_.advertise<nav_msgs::Path>("path", 1); } ``` 3. 在地图、当前位置和目标位置的回调函数中,需要将接收到的信息保存到对应的成员变量中。 ```c++ void EgoPlanner::mapCallback(const nav_msgs::OccupancyGrid::ConstPtr& msg) { map_ = *msg; } void EgoPlanner::poseCallback(const geometry_msgs::PoseStamped::ConstPtr& msg) { start_ = *msg; } void EgoPlanner::goalCallback(const geometry_msgs::PoseStamped::ConstPtr& msg) { goal_ = *msg; } ``` 4. 在路径规划函数中,需要调用路径规划算法,生成一条可行的路径,并将路径发布出去。 ```c++ void EgoPlanner::plan() { // 调用路径规划算法,生成一条可行的路径 std::vector<geometry_msgs::PoseStamped> path = pathPlanning(map_, start_, goal_); // 将路径发布出去 nav_msgs::Path path_msg; path_msg.header.frame_id = "map"; path_msg.header.stamp = ros::Time::now(); path_msg.poses = path; pub_path_.publish(path_msg); } ``` 5. 在主函数中,创建EgoPlanner对象,并进入ROS循环。 ```c++ int main(int argc, char** argv) { ros::init(argc, argv, "ego_planner"); EgoPlanner planner; ros::Rate rate(10); while (ros::ok()) { planner.plan(); ros::spinOnce(); rate.sleep(); } return 0; } ``` 以上就是Ego-Planner的代码框架,其中路径规划算法需要根据具体情况进行选择和实现。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值