• ROS1云课→31欢乐卷假期


    ROS1云课→30导航仿真演示


     


    新增加一个主题地图:

    sudo thunar

    使用超级权限打开:

    复制节日专属地图:

     

    然后修改使用如下配置:

    1. export TURTLEBOT_STDR_MAP_FILE=/opt/ros/kinetic/share/turtlebot_stdr/maps/wish.yaml
    2. roslaunch turtlebot_stdr turtlebot_in_stdr.launch

     

    启动后,效果如下: 

    如何在其中引入导航和区域覆盖?

    区域覆盖



    多点巡逻如何实现?

    如何使用新功能如smach

    何时使用SMACH?
    当希望机器人执行一些复杂的计划时,SMACH非常有用,其中可以明确描述所有可能的状态和状态转换。这基本上消除了将不同模块集成在一起的黑客行为,使移动机器人操作器等系统做一些有趣的事情。
    快速原型:基于Python的简单SMACH语法使快速原型化状态机和开始运行状态机变得容易。
    复杂状态机:SMACH允许设计、维护和调试大型、复杂的分层状态机。可以在这里找到一个复杂的分层状态机示例。
    内省:SMACH在状态机、状态转换、数据流等方面为您提供了全面的内省。有关更多详细信息,请参阅SMACH_viewer。


    何时不应使用SMACH?
    非结构化任务:SMACH将无法满足任务日程安排的要求。
    低级系统:SMACH不是用来作为需要高效率的低级系统的状态机,SMACH是一种任务级架构。
    粉碎:当想粉碎某物时,不要使用SMACH,因为那样会用到粉碎smash。

    SMACH只是一个有限状态机库吗?
    可以使用SMACH构建有限状态机,但SMACH可以做得更多。SMACH是一个用于任务级执行和协调的库,并提供了几种类型的“状态容器”。一个这样的容器是有限状态机,但这个容器也可以是另一个容器中的状态。有关SMACH中内置的容器和状态的列表,请参阅教程页面。 

    如果通过一个cpp案例实现?参考如下:

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. #include
    7. #include
    8. #include
    9. #include
    10. #include
    11. #include
    12. struct Pose
    13. {
    14. double x, y, theta;
    15. std::string frame;
    16. };
    17. class Multigoal
    18. {
    19. private:
    20. void callActionServer(move_base_msgs::MoveBaseGoal goal);
    21. void getGoals();
    22. void setGoals(Pose final_pose,double goal_num);
    23. void run(int status);
    24. int goal_count;
    25. bool goal_reached ,goal_sended, operation_started;
    26. double real_start_time, real_end_time;
    27. double new_pose_x , new_pose_y , old_pose_x , old_pose_y, dist;
    28. int i , j;
    29. ros::NodeHandle nh_;
    30. ros::Subscriber sub;
    31. ros::Subscriber sub2;
    32. ros::Subscriber odom_sub;
    33. move_base_msgs::MoveBaseGoal goal;
    34. move_base_msgs::MoveBaseGoal goal2;
    35. int check_status(int status);
    36. double get_start_time(double start_time);
    37. double get_end_time(double end_time);
    38. double calculate_distance(double curr_pos, double last_pos);
    39. int goal_status;
    40. // std::map goal_map_;
    41. public:
    42. void resultCallback(const actionlib_msgs::GoalStatusArray::ConstPtr &msg);
    43. void odomCallback(const nav_msgs::Odometry::Ptr &msg);
    44. Multigoal(ros::NodeHandle nh);
    45. ~Multigoal();
    46. };
    47. Multigoal::Multigoal(ros::NodeHandle nh)
    48. {
    49. i = 0;
    50. j = 0;
    51. getGoals();
    52. odom_sub = nh.subscribe("/husky_velocity_controller/odom",1,&Multigoal::odomCallback,this);
    53. sub = nh.subscribe("/move_base/status",1,&Multigoal::resultCallback,this);
    54. goal_count = 0;
    55. goal_status = 0;
    56. operation_started = false;
    57. old_pose_x = 0; old_pose_y = 0;
    58. dist = 0;
    59. }
    60. Multigoal::~Multigoal()
    61. {
    62. }
    63. void Multigoal::run(int status)
    64. {
    65. if (status == 3 && goal_count == 0) { // this is the first stage
    66. // still in the first stage but already in some position from previous action
    67. goal_reached = false;
    68. callActionServer(goal);
    69. goal_count = goal_count + 1;
    70. }
    71. if(goal_count == 1 && status == 1)
    72. {
    73. // already succesfully sending the goal.
    74. goal_count = goal_count + 1;
    75. }
    76. if (goal_count == 2 && status == 3) {
    77. // already send the goal and the first goal is reached
    78. callActionServer(goal2);
    79. goal_count = goal_count + 1;
    80. }
    81. if (goal_count == 3 && status == 1) {
    82. // already successfully sending the second goal.
    83. goal_count = goal_count + 1;
    84. }
    85. if (goal_count == 4 && status == 3) {
    86. ROS_INFO("all goal has reaced succesfully!");
    87. goal_count = goal_count + 1;
    88. operation_started = false;
    89. ROS_INFO("total distance traveled : %f",dist);
    90. }
    91. else
    92. {
    93. //do nothing
    94. }
    95. }
    96. int Multigoal::check_status(int status)
    97. {
    98. goal_status = status;
    99. // ROS_INFO("goal_status %i",goal_status);
    100. if (goal_status == 1) {
    101. // ROS_INFO("goal_sended ");
    102. goal_sended = true;
    103. goal_reached = false;
    104. }
    105. if (goal_status == 3)
    106. {
    107. // ROS_INFO("goal reached");
    108. goal_reached = true;
    109. goal_sended = false;
    110. }
    111. run(goal_status);
    112. return goal_status;
    113. // check the current status
    114. }
    115. double Multigoal::get_start_time(double start_time)
    116. {
    117. if (start_time > 0 && i < 1 ) {
    118. real_start_time = start_time;
    119. operation_started = true;
    120. std::cout << "real start time is :" << real_start_time << std::endl;
    121. return real_start_time;
    122. }
    123. }
    124. double Multigoal::get_end_time(double end_time){
    125. if (end_time > 0 && j < 1 ) {
    126. real_end_time = end_time;
    127. std::cout << "real end time is :" << real_end_time << std::endl;
    128. return real_end_time;
    129. }
    130. }
    131. void Multigoal::odomCallback(const nav_msgs::Odometry::Ptr & msg)
    132. {
    133. if (operation_started) {
    134. new_pose_x = msg->pose.pose.position.x;
    135. new_pose_y = msg->pose.pose.position.y;
    136. double diff_x , diff_y;
    137. diff_x = new_pose_x - old_pose_x;
    138. diff_y = new_pose_y - old_pose_y;
    139. dist = calculate_distance(diff_x,diff_y) + dist;
    140. old_pose_x = new_pose_x; old_pose_y = new_pose_y;
    141. }
    142. else
    143. {
    144. //
    145. }
    146. }
    147. double Multigoal::calculate_distance(double diff_x, double diff_y)
    148. {
    149. // calculate the distance
    150. double result = hypot (diff_x, diff_y);
    151. return result;
    152. }
    153. void Multigoal::resultCallback(const actionlib_msgs::GoalStatusArray::ConstPtr &msg){
    154. // check if goal is reached
    155. int goal_stat;
    156. if (msg->status_list.empty()) {
    157. goal_stat = 3;
    158. }
    159. else
    160. {
    161. goal_stat = msg->status_list[0].status;
    162. }
    163. check_status(goal_stat);
    164. double start_time , finish_time;
    165. if (goal_count == 1)
    166. {
    167. // status is not clear, no goal is sended yet!
    168. start_time = msg->header.stamp.toSec(); // get the time from message
    169. get_start_time(start_time);
    170. i = i + 1;
    171. // getGoals();
    172. }
    173. if ( goal_count == 5)
    174. {
    175. finish_time = msg->header.stamp.toSec(); // get the time from message
    176. get_end_time(finish_time);
    177. j = j + 1;
    178. double total_time = abs(real_start_time - real_end_time);
    179. ROS_INFO("total time = %f",total_time);
    180. goal_count = goal_count + 1;
    181. }
    182. }
    183. void Multigoal::getGoals()
    184. {
    185. std::string param_name;
    186. if (nh_.searchParam("/multi_goal/multi_goal_driver/goals", param_name))
    187. {
    188. XmlRpc::XmlRpcValue goals;
    189. if (!nh_.hasParam("/multi_goal/multi_goal_driver/goals"))
    190. {
    191. ROS_ERROR("No stations on parameterserver");
    192. }
    193. nh_.getParam("/multi_goal/multi_goal_driver/goals", goals);
    194. for (size_t i = 0 ; i < goals.size(); i++)
    195. {
    196. XmlRpc::XmlRpcValue goal = goals[i];
    197. Pose final_pose;
    198. XmlRpc::XmlRpcValue poses = goal["poses"];
    199. std::string frame = goal["frame_id"];
    200. XmlRpc::XmlRpcValue pose_back = poses[poses.size()-1];
    201. final_pose.x = pose_back[0];
    202. final_pose.y = pose_back[1];
    203. final_pose.theta = pose_back[2];
    204. final_pose.frame = frame;
    205. setGoals(final_pose,i);
    206. }
    207. // after the goal has been obtained, now run the code to go to the destination
    208. }
    209. else
    210. {
    211. ROS_INFO("No param 'goals' found in an upward search");
    212. }
    213. }
    214. void Multigoal::setGoals(Pose final_pose,double goal_num)
    215. {
    216. if (goal_num == 0) {
    217. geometry_msgs::PoseStamped target_pose;
    218. //we'll send a goal to the robot to move 1 meter forward
    219. goal.target_pose.header.frame_id = final_pose.frame;
    220. goal.target_pose.header.stamp = ros::Time::now();
    221. goal.target_pose.pose.position.x = final_pose.x;
    222. goal.target_pose.pose.orientation.w = final_pose.theta;
    223. std::cout << "first goal is : " << final_pose.x << ", " << final_pose.y << ", " << final_pose.theta << ", " << final_pose.frame << std::endl;
    224. }
    225. if (goal_num == 1)
    226. {
    227. geometry_msgs::PoseStamped target_pose;
    228. //we'll send a goal to the robot to move 1 meter forward
    229. goal2.target_pose.header.frame_id = final_pose.frame;
    230. goal2.target_pose.header.stamp = ros::Time::now();
    231. goal2.target_pose.pose.position.x = final_pose.x;
    232. goal2.target_pose.pose.orientation.w = final_pose.theta;
    233. std::cout << " second goal is: " << final_pose.x << ", " << final_pose.y << ", " << final_pose.theta << ", " << final_pose.frame << std::endl;
    234. }
    235. }
    236. void Multigoal::callActionServer(move_base_msgs::MoveBaseGoal goal)
    237. {
    238. typedef actionlib::SimpleActionClient MoveBaseClient;
    239. MoveBaseClient ac("/move_base", true);
    240. while(!ac.waitForServer(ros::Duration(5.0))){
    241. ROS_INFO("Waiting for the move_base action server to come up");
    242. }
    243. //we'll send a goal to the robot the goal we get from previous function
    244. ac.sendGoal(goal);
    245. ROS_INFO("Sending goal");
    246. }
    247. int main(int argc, char** argv){
    248. ros::init(argc,argv,"multi_goal_driver");
    249. ros::NodeHandle nh;
    250. Multigoal Multigoal(nh);
    251. ros::Rate rate(5);
    252. ros::spin();
    253. return 0;
    254. //wait for the action server to come up
    255. }

    python案例参考:

    1. #!/usr/bin/env python
    2. from random import sample
    3. from math import pow, sqrt
    4. from actionlib_msgs.msg import *
    5. from geometry_msgs.msg import Pose, PoseWithCovarianceStamped, Point, Quaternion, Twist
    6. from move_base_msgs.msg import MoveBaseAction, MoveBaseGoal
    7. import rospy
    8. import actionlib
    9. class MultiPointNav():
    10. def __init__(self):
    11. rospy.init_node('multi_point_nav', anonymous=True)
    12. rospy.on_shutdown(self.shutdown)
    13. # How long in seconds should the robot pause at each location?
    14. self.rest_time = rospy.get_param("~rest_time", 10)
    15. # Are we running in the fake simulator?
    16. self.fake_test = rospy.get_param("~fake_test", False)
    17. # Goal state return values
    18. goal_states = ['PENDING', 'ACTIVE', 'PREEMPTED',
    19. 'SUCCEEDED', 'ABORTED', 'REJECTED',
    20. 'PREEMPTING', 'RECALLING', 'RECALLED',
    21. 'LOST']
    22. locations = dict()
    23. locations['Point1'] = Pose(Point(-15.2, -21.2, 0.000), Quaternion(0.000, 0.000, -0.60710, 0.70710))
    24. locations['Point2'] = Pose(Point(-14.1, -17.1, 0.000), Quaternion(0.000, 0.000, -0.670, 0.743))
    25. locations['Point3'] = Pose(Point(-3.719, 4.401, 0.000), Quaternion(0.000, 0.000, 0.733, 0.680))
    26. locations['Point4'] = Pose(Point(0.720, 2.229, 0.000), Quaternion(0.000, 0.000, 0.786, 0.618))
    27. #locations['Point5'] = Pose(Point(1.471, 1.007, 0.000), Quaternion(0.000, 0.000, 0.480, 0.877))
    28. #locations['Point6'] = Pose(Point(-0.861, -0.019, 0.000), Quaternion(0.000, 0.000, 0.892, -0.451))
    29. # Publisher to manually control the robot (e.g. to stop it, queue_size=5)
    30. self.cmd_vel_pub = rospy.Publisher('cmd_vel', Twist, queue_size=5)
    31. # Subscribe to the move_base action server
    32. self.move_base = actionlib.SimpleActionClient("move_base", MoveBaseAction)
    33. rospy.loginfo("Waiting for move_base action server...")
    34. # Wait 60 seconds for the action server to become available
    35. self.move_base.wait_for_server(rospy.Duration(60))
    36. rospy.loginfo("Connected to move base server")
    37. # A variable to hold the initial pose of the robot to be set by
    38. # the user in RViz
    39. initial_pose = PoseWithCovarianceStamped()
    40. # Variables to keep track of success rate, running time,
    41. # and distance traveled
    42. n_locations = len(locations)
    43. n_goals = 0
    44. n_successes = 0
    45. i = n_locations
    46. distance_traveled = 0
    47. start_time = rospy.Time.now()
    48. running_time = 0
    49. location = ""
    50. last_location = ""
    51. # Get the initial pose from the user
    52. rospy.loginfo("*** Click the 2D Pose Estimate button in RViz to set the robot's initial pose...")
    53. rospy.wait_for_message('initialpose', PoseWithCovarianceStamped)
    54. self.last_location = Pose()
    55. rospy.Subscriber('initialpose', PoseWithCovarianceStamped, self.update_initial_pose)
    56. # Make sure we have the initial pose
    57. while initial_pose.header.stamp == "":
    58. rospy.sleep(1)
    59. rospy.loginfo("Starting navigation test")
    60. # Begin the main loop and run through a sequence of locations
    61. while not rospy.is_shutdown():
    62. # If we've gone through the current sequence,
    63. # start with a new random sequence
    64. if i == n_locations:
    65. i = 0
    66. sequence = ['Point1','Point2','Point3','Point4']
    67. # Skip over first location if it is the same as
    68. # the last location
    69. if sequence[0] == last_location:
    70. i = 1
    71. # Get the next location in the current sequence
    72. location = sequence[i]
    73. # Keep track of the distance traveled.
    74. # Use updated initial pose if available.
    75. if initial_pose.header.stamp == "":
    76. distance = sqrt(pow(locations[location].position.x -
    77. locations[last_location].position.x, 2) +
    78. pow(locations[location].position.y -
    79. locations[last_location].position.y, 2))
    80. else:
    81. rospy.loginfo("Updating current pose.")
    82. distance = sqrt(pow(locations[location].position.x -
    83. initial_pose.pose.pose.position.x, 2) +
    84. pow(locations[location].position.y -
    85. initial_pose.pose.pose.position.y, 2))
    86. initial_pose.header.stamp = ""
    87. # Store the last location for distance calculations
    88. last_location = location
    89. # Increment the counters
    90. i += 1
    91. n_goals += 1
    92. # Set up the next goal location
    93. self.goal = MoveBaseGoal()
    94. self.goal.target_pose.pose = locations[location]
    95. self.goal.target_pose.header.frame_id = 'map'
    96. self.goal.target_pose.header.stamp = rospy.Time.now()
    97. # Let the user know where the robot is going next
    98. rospy.loginfo("Going to: " + str(location))
    99. # Start the robot toward the next location
    100. self.move_base.send_goal(self.goal)
    101. # Allow 5 minutes to get there
    102. finished_within_time = self.move_base.wait_for_result(rospy.Duration(300))
    103. # Check for success or failure
    104. if not finished_within_time:
    105. self.move_base.cancel_goal()
    106. rospy.loginfo("Timed out achieving goal")
    107. else:
    108. state = self.move_base.get_state()
    109. if state == GoalStatus.SUCCEEDED:
    110. rospy.loginfo("Goal succeeded!")
    111. n_successes += 1
    112. distance_traveled += distance
    113. rospy.loginfo("State:" + str(state))
    114. else:
    115. rospy.loginfo("Goal failed with error code: " + str(goal_states[state]))
    116. # How long have we been running?
    117. running_time = rospy.Time.now() - start_time
    118. running_time = running_time.secs / 60.0
    119. # Print a summary success/failure, distance traveled and time elapsed
    120. rospy.loginfo("Success so far: " + str(n_successes) + "/" +
    121. str(n_goals) + " = " +
    122. str(100 * n_successes/n_goals) + "%")
    123. rospy.loginfo("Running time: " + str(trunc(running_time, 1)) +
    124. " min Distance: " + str(trunc(distance_traveled, 1)) + " m")
    125. rospy.sleep(self.rest_time)
    126. def update_initial_pose(self, initial_pose):
    127. self.initial_pose = initial_pose
    128. def shutdown(self):
    129. rospy.loginfo("Stopping the robot...")
    130. self.move_base.cancel_goal()
    131. rospy.sleep(2)
    132. self.cmd_vel_pub.publish(Twist())
    133. rospy.sleep(1)
    134. def trunc(f, n):
    135. # Truncates/pads a float f to n decimal places without rounding
    136. slen = len('%.*f' % (n, f))
    137. return float(str(f)[:slen])
    138. if __name__ == '__main__':
    139. try:
    140. MultiPointNav()
    141. rospy.spin()
    142. except rospy.ROSInterruptException:
    143. rospy.loginfo("AMCL navigation test finished.")

     


     

    [stdr_gui_node_63383890b90245a083c4839a_6417_7727749313635804950-5] process has died [pid 6463, exit code -11, cmd /opt/ros/kinetic/lib/stdr_gui/stdr_gui_node __name:=stdr_gui_node_63383890b90245a083c4839a_6417_7727749313635804950 __log:=/home/shiyanlou/.ros/log/f43b8780-4188-11ed-9830-0242c0a82a04/stdr_gui_node_63383890b90245a083c4839a_6417_7727749313635804950-5.log].
    log file: /home/shiyanlou/.ros/log/f43b8780-4188-11ed-9830-0242c0a82a04/stdr_gui_node_63383890b90245a083c4839a_6417_7727749313635804950-5*.log
    需要更新对应软件包,稳定性会好一些,仅此而已。 


     

  • 相关阅读:
    C++ vector模拟实现
    摘要与关键词 写作
    一文详解手眼标定公式推导
    【JVM技术专题】 深入学习JIT编译器实现机制「 原理篇」
    Vue 3 中的 setup 函数是如何工作的?
    安卓常见设计模式3.2------工厂模式,工厂方法模式,抽象工厂模式对比(Kotlin版)
    springBoot集成swagger3.0.0
    dotNet8 全局异常处理
    chrome插件开发入门-保姆级攻略
    Java计算机毕业设计德云社剧场网上售票系统源码+系统+数据库+lw文档
  • 原文地址:https://blog.csdn.net/ZhangRelay/article/details/127137394