简述:
在这个项目中,将创建一个机器人,它将进入一个迷宫形式的房间,然后从另一个点离开房间。
详细:
在行业中,有些地方机器人可以收集加工过的物体并将这些物体放入仓库。所以这里在这个对象收集过程中,机器人需要进入机器加工区域,它应该从机器加工区域出来。机器人进入机器区域本质上类似于房间入口,机器人从机器区域出来也称为房间出口。
所以在这个项目中,将开发一个机器人应用程序,该应用程序应该在规定的入口位置进入房间,并通过测量距离来识别机器人进入路径和离开房间的物体/墙壁的距离与规定的出口地点。
为了寻找距离,通常使用激光雷达。通过将 激光测距仪集成到机器人中,将能够找到物体或墙壁的距离。这里需要借助ROS导航算法在STDR模拟器上进出房间。
案例方法也适用于机器人寻宝等竞赛场景。
涉及知识点多且杂。需要熟练掌握1-28节全部内容。
全局路径规划知识点:
ROS1云课→20迷宫不惑之A*大法(一种虽古老但实用全局路径规划算法)
实际地图:
简化地图:
机器人:
参考文首链接。
迷宫算法从基础到仿真。
未改进版本视频:
maze_stdr_01
配置文件参考:
export TURTLEBOT_STDR_MAP_FILE=/home/shiyanlou/Code/demo_ws/src/turtlebot_stdr/maps/maze.yaml
- image: maze.png
- resolution: 0.1
- origin: [0.0, 0.0, 0.0]
- occupied_thresh: 0.6
- free_thresh: 0.3
- negate: 0
- <launch>
- <arg name="base" default="$(optenv TURTLEBOT_BASE kobuki)"/>
- <arg name="stacks" default="$(optenv TURTLEBOT_STACKS hexagons)"/>
- <arg name="3d_sensor" default="$(optenv TURTLEBOT_3D_SENSOR kinect)"/>
- <arg name="laser_topic" default="robot0/laser_0"/>
- <arg name="odom_topic" default="robot0/odom"/>
- <arg name="odom_frame_id" default="map"/>
- <arg name="base_frame_id" default="robot0"/>
- <arg name="global_frame_id" default="world"/>
-
- <arg name="map_file" default="$(env TURTLEBOT_STDR_MAP_FILE)"/>
- <arg name="initial_pose_x" default="0.5"/>
- <arg name="initial_pose_y" default="15.5"/>
- <arg name="initial_pose_a" default="0.0"/>
- <arg name="min_obstacle_height" default="0.0"/>
- <arg name="max_obstacle_height" default="5.0"/>
-
-
- <include file="$(find stdr_robot)/launch/robot_manager.launch" />
-
- <node pkg="stdr_server" type="stdr_server_node" name="stdr_server" output="screen" args="$(arg map_file)"/>
-
- <node pkg="stdr_robot" type="robot_handler" name="$(anon robot_spawn)" args="add $(find turtlebot_stdr)/robot/turtlebot.yaml $(arg initial_pose_x) $(arg initial_pose_y) 0"/>
-
- <include file="$(find stdr_gui)/launch/stdr_gui.launch"/>
-
- <include file="$(find turtlebot_stdr)/launch/includes/relays.launch.xml"/>
-
-
- <include file="$(find turtlebot_bringup)/launch/includes/robot.launch.xml">
- <arg name="base" value="$(arg base)" />
- <arg name="stacks" value="$(arg stacks)" />
- <arg name="3d_sensor" value="$(arg 3d_sensor)" />
- include>
- <node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher">
- <param name="use_gui" value="true"/>
- node>
-
-
- <node pkg="nodelet" type="nodelet" name="mobile_base_nodelet_manager" args="manager"/>
- <node pkg="nodelet" type="nodelet" name="cmd_vel_mux" args="load yocs_cmd_vel_mux/CmdVelMuxNodelet mobile_base_nodelet_manager">
- <param name="yaml_cfg_file" value="$(find turtlebot_bringup)/param/mux.yaml"/>
- <remap from="cmd_vel_mux/output" to="mobile_base/commands/velocity"/>
- node>
-
-
- <node name="map_server" pkg="map_server" type="map_server" args="$(arg map_file)">
- <param name="frame_id" value="$(arg global_frame_id)"/>
- node>
-
-
-
- <include file="$(find turtlebot_navigation)/launch/includes/move_base.launch.xml">
- <arg name="odom_topic" value="$(arg odom_topic)"/>
- <arg name="laser_topic" value="$(arg laser_topic)"/>
- <arg name="odom_frame_id" value="$(arg odom_frame_id)"/>
- <arg name="base_frame_id" value="$(arg base_frame_id)"/>
- <arg name="global_frame_id" value="$(arg global_frame_id)"/>
- include>
-
-
- <param name="move_base/local_costmap/obstacle_layer/scan/min_obstacle_height" value="$(arg min_obstacle_height)"/>
- <param name="move_base/local_costmap/obstacle_layer/scan/max_obstacle_height" value="$(arg max_obstacle_height)"/>
- <param name="move_base/global_costmap/obstacle_layer/scan/min_obstacle_height" value="$(arg min_obstacle_height)"/>
- <param name="move_base/global_costmap/obstacle_layer/scan/max_obstacle_height" value="$(arg max_obstacle_height)"/>
-
-
- <include file="$(find turtlebot_navigation)/launch/includes/amcl/amcl.launch.xml">
- <arg name="scan_topic" value="$(arg laser_topic)"/>
- <arg name="use_map_topic" value="true"/>
- <arg name="odom_frame_id" value="$(arg odom_frame_id)"/>
- <arg name="base_frame_id" value="$(arg base_frame_id)"/>
- <arg name="global_frame_id" value="$(arg global_frame_id)"/>
- <arg name="initial_pose_x" value="$(arg initial_pose_x)"/>
- <arg name="initial_pose_y" value="$(arg initial_pose_y)"/>
- <arg name="initial_pose_a" value="$(arg initial_pose_a)"/>
- include>
-
-
- <node name="tf_connector" pkg="turtlebot_stdr" type="tf_connector.py" output="screen"/>
-
-
- <node name="rviz" pkg="rviz" type="rviz" args="-d $(find turtlebot_stdr)/rviz/robot_navigation.rviz"/>
-
-
-
-
- launch>
- shiyanlou:~/ $ history [22:37:23]
- 1 gedit init.sh
- 2 chmod +x init.sh
- 3 ./init.sh
- 4 git clone https://gitcode.net/ZhangRelay/ros_book.git
- 5 cd ros_book
- 6 unzip turtlebot_simulator-melodic.zip
- 7 sudo apt install ros-kinetic-turtlebot-simulator
- 8 catkin_make
- 9 source devel/setup.zsh
- 10 export TURTLEBOT_STDR_MAP_FILE=/home/shiyanlou/Code/demo_ws/src/turtlebot_stdr/maps/maze.yaml
- 11 roslaunch turtlebot_stdr turtlebot_in_stdr.launch
- 12 source devel/setup.zsh
- 13 roslaunch turtlebot_stdr turtlebot_in_stdr.launch
- 14 export TURTLEBOT_STDR_MAP_FILE=/home/shiyanlou/Code/demo_ws/src/turtlebot_stdr/maps/hospital_section.yaml
- 15 export TURTLEBOT_STDR_MAP_FILE=/home/shiyanlou/Code/demo_ws/src/turtlebot_stdr/maps/hospital_section.yaml
- 16 roslaunch turtlebot_stdr turtlebot_in_stdr.launch
- 17 export TURTLEBOT_STDR_MAP_FILE=/home/shiyanlou/Code/demo_ws/src/turtlebot_stdr/maps/maze.yaml
- 18 roslaunch turtlebot_stdr turtlebot_in_stdr.launch
- // Simple Maze Generator in C++ by Jakub Debski '2006
-
- #include
- #include
- #include
- using namespace std;
-
- int main()
- {
- srand(time(0));
-
- const int maze_size_x=80;
- const int maze_size_y=25;
- vector < vector < bool > > maze;
- list < pair < int, int> > drillers;
-
- maze.resize(maze_size_y);
- for (size_t y=0;y
- maze[y].resize(maze_size_x);
-
- for (size_t x=0;x
- for (size_t y=0;y
- maze[y][x]=false;
-
- drillers.push_back(make_pair(maze_size_x/2,maze_size_y/2));
- while(drillers.size()>0)
- {
- list < pair < int, int> >::iterator m,_m,temp;
- m=drillers.begin();
- _m=drillers.end();
- while (m!=_m)
- {
- bool remove_driller=false;
- switch(rand()%4)
- {
- case 0:
- (*m).second-=2;
- if ((*m).second<0 || maze[(*m).second][(*m).first])
- {
- remove_driller=true;
- break;
- }
- maze[(*m).second+1][(*m).first]=true;
- break;
- case 1:
- (*m).second+=2;
- if ((*m).second>=maze_size_y || maze[(*m).second][(*m).first])
- {
- remove_driller=true;
- break;
- }
- maze[(*m).second-1][(*m).first]=true;
- break;
- case 2:
- (*m).first-=2;
- if ((*m).first<0 || maze[(*m).second][(*m).first])
- {
- remove_driller=true;
- break;
- }
- maze[(*m).second][(*m).first+1]=true;
- break;
- case 3:
- (*m).first+=2;
- if ((*m).first>=maze_size_x || maze[(*m).second][(*m).first])
- {
- remove_driller=true;
- break;
- }
- maze[(*m).second][(*m).first-1]=true;
- break;
- }
- if (remove_driller)
- m = drillers.erase(m);
- else
- {
- drillers.push_back(make_pair((*m).first,(*m).second));
- // uncomment the line below to make the maze easier
- // if (rand()%2)
- drillers.push_back(make_pair((*m).first,(*m).second));
-
- maze[(*m).second][(*m).first]=true;
- ++m;
- }
- }
- }
-
- // Done
- for (size_t y=0;y
- for (size_t x=0;x
- {
- if (maze[y][x]==true)
- printf(".");
- else
- printf("#");
- }
-
- return 0;
- }
######.........#.#.......#.....#...#.....#.........#.#...#.#.......#.......#####
######.#.###.#.#.#.#######.#.#####.#.###.#.#.#####.#.###.#.#.#######.###########
.....#.#.#...#.#.........#.#.#.....#.###...#.#.....#.......#.......#.....#######
.#.#.###.#.#####.#.#.#######.#.#.#.#.#####################.#.###.#######.#######
.#.#.#...#...#...#.#...#.#.#.#.#.#.#.........#.....#...........#.#.............#
####.#.#######.#######.#.#.#.#.#.#######.#.#.#.#.#.#.#######.#######.#######.#.#
##...#...#####.#.#####.#...#...#.#...#.#.#.#...#.#...###...#.#.......#.......#.#
####.###.#####.#.#####.#.###.#.###.###.#.#.###.#########.#####.###.#############
.........###.#.....###.#...#.#.#.#.......#.#...#...#.#.#.#.......#.###...#.....#
########.###.#.#.#.###.#.#.###.#.#.#####.#.###.#.###.#.#.#.#.###.#####.###.#.###
.......#.....#.#.#.#...#.#...........#...#.#.....#.......#.#...#.#.........#...#
####.#.#.#####.#.###.#######.#######.###.#.#.###.#.#####.#.#####.#.#.#####.#####
...#.#.#.......#...#.....#.....#.#...#####.#...#.......#.#...#.....#...#.#.....#
##.###.#.#.#.###.#####.#.#####.#.#.#######.#####.#####.#.###.#.###.#####.#####.#
##...#...#.#.#.......#.#.....#...#.......#...#...#.....#.....#...#...........#.#
####.#.###########.###.#.###.#####.#######.###.###########.###.###.#####.###.###
####...###.....#...#.#.#...#...........###...#.###...#.###.###...#.....#.#.....#
####.#####.#######.#.###.###.#.#####.#.#############.#.###.#####.#####.#.###.###
####.........#.#...#.....#.#.#.#.....#.###.#...#.............#...#####.#...#...#
######.#.#####.#.###.#.#.#.###.#######.###.#.#####.###.#################.#######
######.#...#.#.....#.#.#.#...#...###...###.....#...#.......#########...#.......#
######.###.#.#####.#####.#.###.#.###.#.###.#.###.###.#####.#########.#########.#
######.#.#.#...###...#...#.#.#.#...#.#.....#.#.#...#.###...#########...#.......#
########.#.###.#######.#.#.#.###.#######.###.#.#####.###############.#.###.#####
########...###.........#.#.......#######.#.....#####.......#########.#.........#
路径规划研究的起源(如下为引用)
问题简介
18世纪初普鲁士的哥尼斯堡,有一条河穿过,河上有两个小岛,有七座桥把两个岛与河岸联系起来(如概述图)。有个人提出一个问题:一个步行者怎样才能不重复、不遗漏地一次走完七座桥,最后回到出发点。后来大数学家欧拉把它转化成一个几何问题——一笔画问题。他不仅解决了此问题,且给出了连通图可以一笔画的充要条件是:奇点的数目不是0个就是2个(连到一点的数目如果是奇数条,就称为奇点;如果是偶数条,就称为偶点。要想一笔画成,必须中间点均是偶点,也就是有来路必有另一条去路,奇点只可能在两端。因此任何图能一笔画成,奇点要么没有,要么在两端) 。
推断方法
当欧拉在1736年访问普鲁士的哥尼斯堡(现俄罗斯加里宁格勒)时,他发现当地的市民正从事一项非常有趣的消遣活动。哥尼斯堡城中有一条名叫Pregel的河流横经其中,这项有趣的消遣活动是在星期六作一次走过所有七座桥的散步,每座桥只能经过一次而且起点与终点必须是同一地点。
欧拉把每一块陆地考虑成一个点,连接两块陆地的桥以线表示。
后来推论出此种走法是不可能的。他的论点是这样的,除了起点以外,每一次当一个人由一座桥进入一块陆地(或点)时,他(或她)同时也由另一座桥离开此点。所以每行经一点时,计算两座桥(或线),从起点离开的线与最后回到始点的线亦计算两座桥,因此每一个陆地与其他陆地连接的桥数必为偶数。
存在问题
著名数学家欧拉的画像
著名数学家欧拉的画像
七桥所成之图形中,没有一点含有偶数条数,因此上述的任务无法完成。
欧拉的这个考虑非常重要,也非常巧妙,它正表明了数学家处理实际问题的独特之处——把一个实际问题抽象成合适的“数学模型”。这种研究方法就是“数学模型方法”。这并不需要运用多么深奥的理论,但想到这一点,却是解决难题的关键。
接下来,欧拉运用图中的一笔画定理为判断准则,很快地就判断出要一次不重复走遍哥尼斯堡的7座桥是不可能的。也就是说,多少年来,人们费脑费力寻找的那种不重复的路线,根本就不存在。一个曾难住了那么多人的问题,竟是这么一个出人意料的答案!
-
相关阅读:
设计模式-单例模式-注册式单例模式-枚举式单例模式和容器式单例模式在Java中的使用示例
系统可靠性分析与设计
【运维篇】Redis常见运维命令详解
pip安装使用清华镜像
nginx.conf配置
Python学习(一)基础语法
Pro_07丨波动率因子3.0与斜率因子
常见的限流算法- python版本
字符串6——实现 strStr()
【Ambari】银河麒麟V10 ARM64架构_安装Ambari2.7.6&HDP3.3.1(HiDataPlus)
-
原文地址:https://blog.csdn.net/ZhangRelay/article/details/126880232