启动fishbot建图程序后应该从哪里提取定位数据?
-
-
@siviechen 你可以尝试slam_toolbox ,相比carto更好用。
ros2 launch slam_toolbox online_async_launch.py
-
@小鱼 我是想自己学写一写slam算法的。cartographer我已经把多少看了一遍了,所以我想了解一些cartographer实现方面的问题,比如上面这些。能教一教吗
-
@siviechen 按照教程应该能跑起来,你遇到什么错误了
-
@小鱼 emm,是这样的:教程里是教我们下载carto源码,然后改配置文件.lua和launch文件,然后启动gazebo仿真,然后跑cartographer,这样做是没问题的,我的也没问题。
而我现在是把启动gazebo的仿真这一步换成了启动fishbot实车,启动了agent来获取scan,odom和imu数据。(在这同时把launch文件里的'use_sim_time'改成了’false‘,因为不是在跑仿真了)
然后我放一张rviz的图:
和一张rqt_graph的图:
我对其的理解是map没有数据,用ros2 topic echo去试也是没有数据跳出来的
不知道要如何才能像小鱼的雷达docker选2那样跑起来
-
@siviechen 看一下tf,还有frameid对不对
-
-
@siviechen 再刷新看看,没有就有大问题了
-
-
@siviechen 用rqt_tf_tree 看
-
@小鱼 ros2好像没有这个功能,rqt_tf_tree: command not found
-
@siviechen 有的,搜一下安装下
-
@小鱼 找到了,贴一下过程:
sudo apt install ros-humble-rqt-tf-tree rm ~/.config/ros.org/rqt_gui.ini #删除缓存,不然报错 ros2 run rqt_tf_tree rqt_tf_tree
但是结果还是一样的:
会和车的雷达要把fixed frame改成laser_frame有关系吗?默认好像是map
-
@siviechen 那就真的可能没人发布frame,你可以把这里的做一下
-
@小鱼 行,我试试
-
@小鱼 我想起来教程里有个fishbot_bringup,我就直接拿来用了。但是虽然有了tf树,算法却还是跑不起起来。过程:
#MicroRos sudo docker run -it --rm -v /dev:/dev -v /dev/shm:/dev/shm --privileged --net=host microros/micro-ros-agent:$ROS_DISTRO udp4 --port 8888 -v6 #laser xhost + && sudo docker run -it --rm -v /dev:/dev -v /dev/shm:/dev/shm --privileged -v /tmp/.X11-unix:/tmp/.X11-unix --device /dev/snd -e DISPLAY=unix$DISPLAY -p 8889:8888 registry.cn-hangzhou.aliyuncs.com/fishros/fishbot_laser #tf ros2 launch fishbot_bringup fishbot_bringup.launch.py #carto ros2 launch fishbot_cartographer cartographer.launch.py #显示tf树 ros2 run rqt_tf_tree rqt_tf_tree #rqt_graph rqt_graph
我个人觉得是ros2新增的qos的问题。启动carto后慢慢翻终端里的信息会找到这么两条:
[cartographer_node-1] [WARN] [1692678150.099094890] [cartographer logger]: W0822 12:22:30.000000 11917 tf_bridge.cpp:53] Lookup would require extrapolation into the past. Requested time 1692678149.889606 but the earliest data is at time 1692678149.949214, when looking up transform from frame [odom] to frame [base_link] [rviz2-3] [WARN] [1692678150.507302604] [rviz2]: New publisher discovered on topic '/scan', offering incompatible QoS. No messages will be sent to it. Last incompatible policy: RELIABILITY_QOS_POLICY [ERROR] [cartographer_node-1]: process has died [pid 11917, exit code -6, cmd '/home/cxw/fishbot_ws/install/cartographer_ros/lib/cartographer_ros/cartographer_node -configuration_directory /home/cxw/fishbot/install/fishbot_cartographer/share/fishbot_cartographer/config -configuration_basename fishbot_2d.lua --ros-args -r __node:=cartographer_node --params-file /tmp/launch_params_w6i5hcn_'].
第二条消息是说进程没了,感觉这应该是rqt_graph里连cartographer_node节点都刷不出来的原因?
小鱼大佬的docker雷达按2启动建图不是很顺利吗,能想到是什么原因吗?
-
@siviechen 改一些fishbot_bringup的代码,改成和教程中的一致:
#include <rclcpp/rclcpp.hpp> #include <nav_msgs/msg/odometry.hpp> #include <tf2/utils.h> #include <tf2_ros/transform_broadcaster.h> class TopicSubscribe01 : public rclcpp::Node { public: TopicSubscribe01(std::string name) : Node(name) { // 创建一个订阅者,订阅"odom"话题的nav_msgs::msg::Odometry类型消息 odom_subscribe_ = this->create_subscription<nav_msgs::msg::Odometry>( "odom", rclcpp::SensorDataQoS(), std::bind(&TopicSubscribe01::odom_callback, this, std::placeholders::_1)); // 创建一个tf2_ros::TransformBroadcaster用于广播坐标变换 tf_broadcaster_ = std::make_unique<tf2_ros::TransformBroadcaster>(this); } private: rclcpp::Subscription<nav_msgs::msg::Odometry>::SharedPtr odom_subscribe_; std::unique_ptr<tf2_ros::TransformBroadcaster> tf_broadcaster_; nav_msgs::msg::Odometry odom_msg_; // 回调函数,处理接收到的odom消息 void odom_callback(const nav_msgs::msg::Odometry::SharedPtr msg) { (void)msg; RCLCPP_INFO(this->get_logger(), "接收到里程计信息->底盘坐标系 tf :(%f,%f)", msg->pose.pose.position.x, msg->pose.pose.position.y); // 更新odom_msg_的姿态信息 odom_msg_.pose.pose.position.x = msg->pose.pose.position.x; odom_msg_.pose.pose.position.y = msg->pose.pose.position.y; odom_msg_.pose.pose.position.z = msg->pose.pose.position.z; odom_msg_.pose.pose.orientation.x = msg->pose.pose.orientation.x; odom_msg_.pose.pose.orientation.y = msg->pose.pose.orientation.y; odom_msg_.pose.pose.orientation.z = msg->pose.pose.orientation.z; odom_msg_.pose.pose.orientation.w = msg->pose.pose.orientation.w; }; public: // 发布坐标变换信息 void publish_tf() { geometry_msgs::msg::TransformStamped transform; double seconds = this->now().seconds(); transform.header.stamp = rclcpp::Time(static_cast<uint64_t>(seconds * 1e9)); transform.header.frame_id = "odom"; transform.child_frame_id = "base_footprint"; transform.transform.translation.x = odom_msg_.pose.pose.position.x; transform.transform.translation.y = odom_msg_.pose.pose.position.y; transform.transform.translation.z = odom_msg_.pose.pose.position.z; transform.transform.rotation.x = odom_msg_.pose.pose.orientation.x; transform.transform.rotation.y = odom_msg_.pose.pose.orientation.y; transform.transform.rotation.z = odom_msg_.pose.pose.orientation.z; transform.transform.rotation.w = odom_msg_.pose.pose.orientation.w; // 广播坐标变换信息 tf_broadcaster_->sendTransform(transform); } }; int main(int argc, char **argv) { // 初始化ROS节点 rclcpp::init(argc, argv); // 创建一个TopicSubscribe01节点 auto node = std::make_shared<TopicSubscribe01>("fishbot_bringup"); // 设置循环频率 rclcpp::WallRate loop_rate(20.0); while (rclcpp::ok()) { // 处理回调函数 rclcpp::spin_some(node); // 发布坐标变换信息 node->publish_tf(); // 控制循环频率 loop_rate.sleep(); } // 关闭ROS节点 rclcpp::shutdown(); return 0; }
-
@小鱼 改完了,有两处不同:
double seconds = this->now().seconds() ; //+ 1.0; #41行 rclcpp::WallRate loop_rate(20.0); //(1000.0); #63行
编译+source了。但是结果还是没有改变