精华内容
下载资源
问答
  • 题:你要改变对象在屏幕的显示顺序,向前或向后移动他们解决办法:使用DisplayObectContainer类中的setChildIndex( ) 方法改变选定项的位置getChildIndex( ) 与getChildAt( )方法用于获取项目在显示对象列表中的位置...
    题:
    你要改变对象在屏幕的显示顺序,向前或向后移动他们
    解决办法:
    使用DisplayObectContainer类中的setChildIndex( ) 方法改变选定项的位置

    getChildIndex( ) 与getChildAt( )方法用于获取项目在显示对象列表中的位置
    讨论:


    setChildIndex( )用于重置容器对象中子对象的显示顺序
    它有两个参数,一个是被移动的子对象,一个被移动子对象新位置的索引值
    注意这个所以值必须是有效的,不能为负数或者大于numchildren
    下面的例子创建了3个不同颜色的圈,蓝色在最上边,setChildIndex( ) 方法被用于将蓝色圈置于其它连个圈的下边
    即改变它在容器中索引值由2变为0,同时其它子对象的位置也发生对应的改变,红色圈的索引值变为1,绿色圈的索引值变为2
    package {
      import flash.display.*;
      public class SetChildIndexExample extends Sprite {
        public function SetChildIndexExample(  ) {
          //在不同位置,创建三个不同颜色的圈
          var red:Shape = createCircle( 0xFF0000, 10 );
          red.x = 10;
          red.y = 20;
          var green:Shape = createCircle( 0x00FF00, 10 );
          green.x = 15;
          green.y = 25;
          var blue:Shape = createCircle( 0x0000FF, 10 );
          blue.x = 20;
          blue.y = 20;
          
          // 将三个圈加入显示对象列表,红色圈的索引值是0, 绿色为 1, 蓝色为 2
          addChild( red );
          addChild( green );
          addChild( blue );
          //移动蓝色圈,让其在另外两个圈的下边
          setChildIndex( blue, 0 );
        }
       
        //创建圈的函数
        public function createCircle( color:uint, radius:Number ):Shape {
          var shape:Shape = new Shape(  );
          shape.graphics.beginFill( color );
          shape.graphics.drawCircle( 0, 0, radius );
          shape.graphics.endFill(  );
          return shape;
        }
      }
    }


    另外就是假设如果你不知道红色圈的位置,但是也想让蓝色圈在红色圈的下边
    你可以用


    getChildIndex( ) 或getChildAt( )配合setChildIndex()来使用

    例如:
    setChildIndex(blue,getChildIndex(red)); 
     
    展开全文
  • 问题: 你要改变对象在屏幕的显示顺序,向前或向后移动他们 解决办法: 使用DisplayObectContainer类中的setChildIndex( ) 方法改变选定项的位置 getChildIndex( ) 与getChildAt( )方法用于获取项目在显示对象列表中...
    问题:
    你要改变对象在屏幕的显示顺序,向前或向后移动他们
    解决办法:
    使用DisplayObectContainer类中的setChildIndex( ) 方法改变选定项的位置

    getChildIndex( ) 与getChildAt( )方法用于获取项目在显示对象列表中的位置
    讨论:


    setChildIndex( )用于重置容器对象中子对象的显示顺序
    它有两个参数,一个是被移动的子对象,一个被移动子对象新位置的索引值
    注意这个所以值必须是有效的,不能为负数或者大于numchildren
    下面的例子创建了3个不同颜色的圈,蓝色在最上边,setChildIndex( ) 方法被用于将蓝色圈置于其它连个圈的下边
    即改变它在容器中索引值由2变为0,同时其它子对象的位置也发生对应的改变,红色圈的索引值变为1,绿色圈的索引值变为2
    package {
      import flash.display.*;
      public class SetChildIndexExample extends Sprite {
        public function SetChildIndexExample(  ) {
          //在不同位置,创建三个不同颜色的圈
          var red:Shape = createCircle( 0xFF0000, 10 );
          red.x = 10;
          red.y = 20;
          var green:Shape = createCircle( 0x00FF00, 10 );
          green.x = 15;
          green.y = 25;
          var blue:Shape = createCircle( 0x0000FF, 10 );
          blue.x = 20;
          blue.y = 20;
          
          // 将三个圈加入显示对象列表,红色圈的索引值是0, 绿色为 1, 蓝色为 2
          addChild( red );
          addChild( green );
          addChild( blue );
          //移动蓝色圈,让其在另外两个圈的下边
          setChildIndex( blue, 0 );
        }
       
        //创建圈的函数
        public function createCircle( color:uint, radius:Number ):Shape {
          var shape:Shape = new Shape(  );
          shape.graphics.beginFill( color );
          shape.graphics.drawCircle( 0, 0, radius );
          shape.graphics.endFill(  );
          return shape;
        }
      }
    }


    另外就是假设如果你不知道红色圈的位置,但是也想让蓝色圈在红色圈的下边
    你可以用


    getChildIndex( ) 或getChildAt( )配合setChildIndex()来使用

    例如:
    setChildIndex(blue,getChildIndex(red)); 
    展开全文
  • 举一个简单的例子,假设您要对机器人进行编程,使其向前移动一个1.0米,旋转180度,然后回到起点。 我们将尝试通过多种不同方式来完成此任务,这些方式将很好地说明ROS中运动控制的不同级别。 So far we have been ...

    7.6 Publishing Twist Messages from a ROS Node (使用ROS节点发布Twist消息)

    到目前为止,我们一直在从命令行移动机器人,但是大多数时候,您将依靠ROS节点来发布适当的Twist消息。 举一个简单的例子,假设您要对机器人进行编程,使其向前移动一个1.0米,旋转180度,然后回到起点。 我们将尝试通过多种不同方式来完成此任务,这些方式将很好地说明ROS中运动控制的不同级别。
    So far we have been moving our robot from the command line, but most of the time you will rely on a ROS node to publish the appropriate Twist messages. As a simple example, suppose you want to program your robot to move one 1.0 meters forward, turn around 180 degrees, then come back to the starting point. We will attempt to accomplish this task a number of different ways which will nicely illustrate the different levels of motion control in ROS.

    7.6.1 Estimating Distance and Rotation Using Time and Speed (使用时间和速度估算距离和旋转)

    我们的第一个尝试是使用定时的Twist命令将机器人向前移动一定距离,旋转180度,然后使用相同的时间和相同的速度再次向前移动,最终如愿的在开始的地方停止运动。 最后,我们再次将机器人再旋转180度以匹配原始方向。
    Our first attempt will be to use timed Twist commands to move the robot forward a certain distance, rotate 180 degrees, then move forward again for the same time and at the same speed where it will hopefully end up where it started. Finally, we will rotate the robot 180 degrees one more time to match the original orientation.

    可以在rbx1_nav / nodes子目录中的文件timed_out_and_back.py中找到该脚本。 在查看代码之前,让我们在ArbotiX模拟器中尝试一下。
    The script can be found in the file timed_out_and_back.py in the rbx1_nav/nodes subdirectory. Before looking at the code, let’s try it in the ArbotiX simulator.

    7.6.2 Timed Out-and-Back in the ArbotiX Simulator (在ArbotiX Simulator中定时往返)

    为了确保将假的Turtlebot重新放置在起始位置,请使用Ctrl-C终止已经运行的假的Turtlebot启动文件,然后使用以下命令再次将其启动:
    To make sure the fake Turtlebot is repositioned at the start location, use Ctrl-C to terminate the fake Turtlebot launch file if you already have it running, then bring it up again with the command:

    roslaunch rbx1_bringup fake_turtlebot.launch
    

    (如果需要,请用Pi Robot或您自己的机器人的那个文件替换fake_turtlebot.launch文件。这不会影响结果。)
    (If desired, replace the fake_turtlebot.launch file with the one for Pi Robot or your own robot. It won’t make a difference to the results.)

    如果RViz尚未运行,请立即启动它:
    If RViz is not already running, fire it up now:

    rosrun rviz rviz -d `rospack find rbx1_nav`/sim.rviz
    

    或单击“重置”按钮来清除以前教程中的所有里程箭头。 最后,运行timed_out_and_back.py节点:
    or click the Reset button to clear any Odometry arrows from the previous section. Finally, run the timed_out_and_back.py node:

    rosrun rbx1_nav timed_out_and_back.py
    

    希望RViz将显示您的机器人执行一次往返动作,最终结果将类似于以下内容:
    Hopefully RViz will show your robot executing an out-and-back maneuver and the end result will look something like the following:
    在这里插入图片描述大箭头表示机器人在其轨迹上各个点的位置和方向,如机器人(假的)内部里程计所报告的那样。 在接下来的几节中,我们将学习如何利用里程表信息。
    The large arrows represent the position and orientation of the robot at various points along its trajectory as reported by the robot’s (fake) internal odometry. We will learn how to make use of this odometry information in the next few sections.

    到目前为止,在理想的模拟器中一切看起来都不错。 但是,在实际的机器人上进行尝试之前,让我们看一下代码。
    So far, things look pretty good in the ideal simulator. But before trying it out on a real robot, let’s look at the code.

    7.6.3 The Timed Out-and-Back Script (定时往返的脚本)

    这是定时往返节点的完整脚本。 整体列出后,我们将其细分为较小的部分。
    Here is the full script for the timed out and back node. After the listing, we will break it down into smaller pieces.

    源连接: timed_out_and_back.py
    Link to source: timed_out_and_back.py

    #!/usr/bin/env python
    
    """ timed_out_and_back.py - Version 1.2 2014-12-14
    
        A basic demo of the using odometry data to move the robot along
        and out-and-back trajectory.
    
        Created for the Pi Robot Project: http://www.pirobot.org
        Copyright (c) 2012 Patrick Goebel.  All rights reserved.
    
        This program is free software; you can redistribute it and/or modify
        it under the terms of the GNU General Public License as published by
        the Free Software Foundation; either version 2 of the License, or
        (at your option) any later version.5
        
        This program is distributed in the hope that it will be useful,
        but WITHOUT ANY WARRANTY; without even the implied warranty of
        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        GNU General Public License for more details at:
        
        http://www.gnu.org/licenses/gpl.html
          
    """
    
    import rospy
    from geometry_msgs.msg import Twist
    from math import pi
    
    class OutAndBack():
        def __init__(self):
            # Give the node a name
            rospy.init_node('out_and_back', anonymous=False)
    
            # Set rospy to execute a shutdown function when exiting       
            rospy.on_shutdown(self.shutdown)
            
            # Publisher to control the robot's speed
            self.cmd_vel = rospy.Publisher('/cmd_vel', Twist, queue_size=1)
            
            # How fast will we update the robot's movement?
            rate = 50
            
            # Set the equivalent ROS rate variable
            r = rospy.Rate(rate)
            
            # Set the forward linear speed to 0.2 meters per second 
            linear_speed = 0.2
            
            # Set the travel distance to 1.0 meters
            goal_distance = 1.0
            
            # How long should it take us to get there?
            linear_duration = goal_distance / linear_speed
            
            # Set the rotation speed to 1.0 radians per second
            angular_speed = 1.0
            
            # Set the rotation angle to Pi radians (180 degrees)
            goal_angle = pi
            
            # How long should it take to rotate?
            angular_duration = goal_angle / angular_speed
         
            # Loop through the two legs of the trip  
            for i in range(2):
                # Initialize the movement command
                move_cmd = Twist()
                
                # Set the forward speed
                move_cmd.linear.x = linear_speed
                
                # Move forward for a time to go the desired distance
                ticks = int(linear_duration * rate)
                
                for t in range(ticks):
                    self.cmd_vel.publish(move_cmd)
                    r.sleep()
                
                # Stop the robot before the rotation
                move_cmd = Twist()
                self.cmd_vel.publish(move_cmd)
                rospy.sleep(1)
                
                # Now rotate left roughly 180 degrees  
                
                # Set the angular speed
                move_cmd.angular.z = angular_speed
    
                # Rotate for a time to go 180 degrees
                ticks = int(goal_angle * rate)
                
                for t in range(ticks):           
                    self.cmd_vel.publish(move_cmd)
                    r.sleep()
                    
                # Stop the robot before the next leg
                move_cmd = Twist()
                self.cmd_vel.publish(move_cmd)
                rospy.sleep(1)    
                
            # Stop the robot
            self.cmd_vel.publish(Twist())
            
        def shutdown(self):
            # Always stop the robot when shutting down the node.
            rospy.loginfo("Stopping the robot...")
            self.cmd_vel.publish(Twist())
            rospy.sleep(1)
     
    if __name__ == '__main__':
        try:
            OutAndBack()
        except:
            rospy.loginfo("Out-and-Back node terminated.")
    
    

    由于这是我们的第一个脚本,因此让我们从顶部开始逐行解释:
    Since this is our first script, let’s take it line-by-line starting from the top:

    #!/usr/bin/env python
    import rospy
    

    如果您使用Python做过ROS入门教程,您将已经知道我们所有的ROS节点都以这两行开头。 第一行确保程序将作为Python脚本运行,而第二行则导入Python的主ROS库。
    If you did the ROS Beginner Tutorials in Python, you’ll already know that all of our ROS nodes begin with these two lines. The first line ensures that the program will run as a Python script while the second imports the main ROS library for Python.

    from geometry_msgs.msg import Twist
    from math import pi
    

    在这里,我们会处理本脚本所需的任何其他需要导入的软件包。 在本案例中,我们将需要ROS geometry_msgs包中的Twist消息类型和Python数学模块中的常数PI。 请注意,导入错误的常见原因是忘记在包的package.xml文件中包括必要的ROS <run_depend>行。 在本案例中,我们的package.xml文件必须包含以下行:
    Here we take care of any other imports we need for the script. In this case, we will need the Twist message type from the ROS geometry_msgs package and the constant pi from the Python math module. Note that a common source of import errors is to forget to include the necessary ROS <run_depend> line in your package’s package.xml file. In this case, our package.xml file has to include the line:

    <run_depend>geometry_msgs</run_depend>
    

    这样我们就可以从geometry_msgs.msg导入Twist了。
    so that we can import Twist from geometry_msgs.msg .

    class OutAndBack():
    	def __init__(self):
    

    在这里,我们将ROS节点的主体定义为Python类并且使用标准类的初始化行进行初始化,以此开始。
    Here we begin the main body of our ROS node by defining it as a Python class along with the standard class initialization line.

    # Give the node a name
    rospy.init_node('out_and_back', anonymous=False)
    # Set rospy to execute a shutdown function when exiting
    rospy.on_shutdown(self.shutdown)
    

    每个ROS节点都需要调用rospy.init_node()函数,并且我们还为on_shutdown()函数设置了一个回调,以便在脚本终止时可以执行任何必要的清除操作,例如 当用户点击Ctrl-C时。 对于移动机器人,最重要的清理任务是停止机器人! 我们稍后将在脚本中看到如何执行此操作。
    Every ROS node requires a call to rospy.init_node() and we also set a callback for the on_shutdown() function so that we can perform any necessary cleanup when the script is terminated—e.g. when the user hits Ctrl-C . In the case of a mobile robot, the most important cleanup task is to stop the robot! We’ll see how to do this later in the script.

    # Publisher to control the robot's speed
    self.cmd_vel = rospy.Publisher('/cmd_vel', Twist, queue_size=5)
    # How fast will we update the robot's movement?
    rate = 50
    # Set the equivalent ROS rate variable
    r = rospy.Rate(rate)
    

    在这里,我们定义了ROS发布器,用于将Twist命令发送到/ cmd_vel话题。 我们还设置了要更新机器人运动的速率(在这种情况下,每秒更新50次),并将queue_size参数设置为5。
    Here we define our ROS publisher for sending Twist commands to the /cmd_vel topic. We also set the rate at which we want to update the robot’s movement, 50 times per second in this case, and the queue_size parameter to 5.

    queue_size参数是在ROS Hydro中引入的,在ROS Jade中是必需的。 在ROS Indigo中,如果不使用此参数初始化发布者,则您的代码将发出警告。 您可以在ROS Wiki上了解有关queue_size参数的更多信息。 要记住的最重要的事实是,如果省略此参数或将其设置为None,则发布者将表现为同步运行。 这意味着,如果发布者的主题有多个订阅者,并且其中一个订阅者被挂起(例如,它位于不稳定的无线连接的另一端),那么发布将阻止该主题的所有订阅者,直到挂起的订阅者 复活。 通常这不是理想的结果。 将queue_size参数设置为数值会导致发布者异步运行,因此每个订阅者都会在单独的线程上接收消息,而没有一个订阅者会锁住整个系统。(发布者同步,导致订阅者只能合用一个线程。发布者异步,订阅者可以用多个线程)
    The queue_size parameter was introduced in ROS Hydro and will be mandatory in ROS Jade. In ROS Indigo, your code will issue a warning if a publisher is initialized without this parameter. You can learn more about the queue_size parameter on the ROS Wiki. The most important fact to keep in mind is that if this parameter is omitted or set to None , the publisher will behave synchronously. This means that if there are multiple subscribers to the publisher’s topic and one of the subscribers gets hung up—for example, it sits at the other end of a flaky wireless connection—then publishing will block on all subscribers to that topic until the hung subscriber comes back to life. This is generally not a desirable outcome. Setting the queue_size parameter to a numeric value causes the publisher to behave asynchronously so that each subscriber receives messages on a separate thread an no one subscriber and lock up the whole system.

    # Set the forward linear speed to 0.2 meters per second
    linear_speed = 0.2
    # Set the travel distance to 1.0 meters
    goal_distance = 1.0# Set the forward linear speed to 0.2 meters per second
    linear_speed = 0.2
    # Set the travel distance to 1.0 meters
    goal_distance = 1.0
    # How long should it take us to get there?
    linear_duration = linear_distance / linear_speed
    

    我们将前进速度初始化为相对安全的每秒0.2米,并将目标距离初始化为1.0米。 然后,我们计算这需要多长时间。
    We initialize the forward speed to a relatively safe 0.2 meters per second and the target distance to 1.0 meters. We then compute how long this should take.

    # Set the rotation speed to 1.0 radians per second
    angular_speed = 1.0
    # Set the rotation angle to Pi radians (180 degrees)
    goal_angle = pi
    # How long should it take to rotate?
    angular_duration = angular_distance / angular_speed
    

    同样,我们将旋转速度设置为每秒1.0弧度,并将目标角度设置为180度或Pi弧度。
    Similarly, we set the rotation speed to 1.0 radians per second and the target angle to 180 degrees or Pi radians.

    # Loop through the two legs of the trip
    for i in range(2):
    	# Initialize the movement command
    	move_cmd = Twist()
    	# Set the forward speed
    	move_cmd.linear.x = linear_speed
    	# Move forward for a time to go the desired distance
    	ticks = int(linear_duration * rate)#总发布次数=发布持续时间(s) * 每秒发布次数
    	for t in range(ticks):#定义了发布次数ticks,到达这个次数之后,就不再发布消息,以前beginner_tutorials的之所以会无限运动,因为用的死循环
    		self.cmd_vel.publish(move_cmd)
    		r.sleep()
    

    这是实际移动机器人的循环-两条腿中的每条腿都有一个循环。 回想一下,一些机器人需要不断发布Twist消息以保持其移动。 因此,为了使机器人以每秒linear_speed米的速度向前移动linear_distance米,我们在适当的持续时间内每1 / rate秒发布一次move_cmd消息。 表达式r.sleep()是rospy.sleep(1 / rate)的缩写,因为我们定义了变量r = rospy.Rate(rate)。
    This is the loop that actually moves the robot—one cycle for each of the two legs. Recall that some robots require a Twist message to be continually published to keep it moving. So to move the robot forward linear_distance meters at a speed of linear_speed meters per second, we publish the move_cmd message every 1/rate seconds for the appropriate duration. The expression r.sleep() is a shorthand for rospy.sleep(1/rate) since we defined the variable r = rospy.Rate(rate) .

    	# Now rotate left roughly 180 degrees
    	# Set the angular speed
    	move_cmd.angular.z = angular_speed
    	# Rotate for a time to go 180 degrees
    	ticks = int(goal_angle * rate)#总发布次数=发布持续时间(s) * 每秒发布次数
    	for t in range(ticks):
    		self.cmd_vel.publish(move_cmd)
    		r.sleep()
    

    在循环的第二部分中,我们以适当的持续时间(在这种情况下为Pi秒)以angular_speed弧度/秒的速度旋转机器人,这应产生180度。
    In the second part of the loop, we rotate the robot at a rate of angular_speed radians per second for the appropriate duration (Pi seconds in this case) which should yield 180 degrees.

    # Stop the robot.
    self.cmd_vel.publish(Twist())
    

    当机器人完成往返行程后,我们通过发布空的Twist消息(所有字段均为0)来停止它。
    When the robot has completed the out-and-back journey, we stop it by publishing an empty Twist message (all fields are 0).

    def shutdown(self):
    	# Always stop the robot when shutting down the node.
    	rospy.loginfo("Stopping the robot...")
    	self.cmd_vel.publish(Twist())
    	rospy.sleep(1)
    

    这是我们的shutdown()回调函数。 如果脚本以任何原因终止,我们将通过发布空的Twist消息来停止机器人。
    This is our shutdown callback function. If the script is terminated for any reason, we stop the robot by publishing an empty Twist message.

    if __name__ == '__main__':
    	try:
    		OutAndBack()
    	except rospy.ROSInterruptException:
    		rospy.loginfo("Out-and-Back node terminated.")
    

    最后,这是用于运行脚本的标准Python模块。 我们只需简单的实例化OutAndBack类即可使脚本(和机器人)运动。
    Finally, this is the standard Python block for running the script. We simply instantiate the OutAndBack class which sets the script (and robot) in motion.

    7.6.4 Timed Out and Back using a Real Robot (使用真实机器人进行定时往返)

    如果您拥有类似TurtleBot的机器人,则可以在现实世界中尝试timed_out_and_back.py脚本。 请记住,我们仅使用时间和速度来估计距离和旋转角度。 因此,我们希望与理想的ArbotiX仿真相比,机器人的惯性会有所帮助(您会记得,该仿真不会对任何物理模型进行建模。)
    If you have a robot like the TurtleBot, you can try the timed_out_and_back.py script in the real world. Remember that we are only using time and speed to estimate distance and rotation angles. So we expect that the robot’s inertia will throw things off compared to the ideal ArbotiX simulation (which, as you will recall, does not model any physics.)

    首先,终止所有正在运行的仿真。 接下来,请确保您的机器人有足够的工作空间-距离机器人至少1.5米,并且两边各有一米。 然后调出机器人的启动文件。 如果您有原始的TurtleBot(iRobot创建基础),使用SSH连接机器人的电脑并运行:
    First, terminate any running simulations. Next, make sure your robot has plenty of room to work in—at least 1.5 meters ahead of it and a meter on either side. Then bring up your robot’s startup launch file(s). If you have an original TurtleBot (iRobot Create base), ssh into the robot’s laptop and run:

    roslaunch rbx1_bringup turtlebot_minimal_create.launch
    

    或者,如果您已经创建了一个启动文件来存储校准参数,则可以使用自己的启动文件。
    Or use your own launch file if you have created one to store your calibration parameters.

    我们还将使用辅助脚本,以便可以在RViz中看到TurtleBot的组合里程表框架。 (这将在下一部分中变得更加清楚。)如果您不使用TurtleBot,则可以跳过此步骤。 此启动文件应使用另一个ssh终端在TurtleBot的电脑上运行:
    We will also use an auxiliary script so that we can see the TurtleBot’s combined odometry frame in RViz . (This will become clearer in the next section.) You can skip this if you are not using a TurtleBot. This launch file should be run on the TurtleBot’s laptop using another ssh terminal:

    roslaunch rbx1_bringup odom_ekf.launch
    

    接下来,我们将配置RViz以显示组合的里程表数据(编码器+陀螺仪),而不是仅显示编码器数据的 /odom。 如果您已经从上一个测试运行了RViz,则只需取消选中Odometry显示并选中Odometry EKF显示,然后跳过以下步骤。
    Next we’re going to configure RViz to display the combined odometry data (encoders + gyro) rather than /odom which only shows the encoder data. If you already have RViz running from the previous test, you can simply un-check the Odometry display and check the Odometry EKF display, then skip the following step.

    如果尚未启动RViz,请立即使用nav_ekf配置文件在工作站上运行它。 该文件只是预选择了/ odom_ekf话题,以显示组合的里程表数据:
    If RViz is not already up, run it now on your workstation with the nav_ekf config file. This file simply pre-selects the / odom_ekf topic for displaying the combined odometry data:

    rosrun rviz rviz -d `rospack find rbx1_nav`/nav_ekf.rviz
    

    此配置与上一个配置之间的唯一区别是,我们现在在/ odom_ekf话题上显示组合的里程表数据,而不仅仅是在/ odom话题上发布的车轮编码器数据。 如果要比较两个显示,可以选中两个显示。
    The only difference between this configuration and the previous one is that we are now displaying the combined odometry data on the /odom_ekf topic rather than just the wheel encoder data published on the /odom topic. You can check both displays if you want to compare the two.

    最后,我们像之前一样运行out和back脚本。 请注意,脚本本身并不关心我们是在运行模拟还是在控制真实的机器人。 它只是在/ cmd_vel话题上发布Twist消息,供任何想听的人使用。 这是ROS如何使我们抽象出运动控制层次结构较低级别的一个示例。 您可以在你的工作站 或 使用ssh登录后的机器人的电脑上运行以下命令:
    Finally, we run the out and back script just like we did before. Note that the script itself does not care if we are running a simulation or controlling a real robot. It is simply publishing Twist messages on the /cmd_vel topic for anyone who cares to listen. This is one example of how ROS allows us to abstract away the lower levels of the motion control hierarchy. You can run the following command either on your workstation or on the robot’s laptop after logging in with ssh :

    rosrun rbx1_nav timed_out_and_back.py
    

    这是在地毯上操作我自己的TurtleBot的结果:
    Here is the result for my own TurtleBot when operating on a low-ply carpet:
    在这里插入图片描述
    从图片中可以看出,机器人最终并没有非常接近起始位置。 首先,它在转身之前走得还不够远(网格正方形相距0.5米)。 然后它在回头之前没有旋转完整的180度。 结果是机器人距离起点左侧约0.5m,并且方向错误。
    As you can tell from the picture, the robot did not end up very close to the starting position. First of all, it did not go far enough before turning around (the grid squares are 0.5 meters apart). Then it did not rotate a full 180 degrees before heading back. The result is that the robot is about 0.5m to the left of the starting point, and it is oriented in the wrong direction.

    幸运的是,我们需要纠正问题的数据直面我们。 上方图像中的大里程计箭头指示了机器人的内部里程计报告的机器人的位置和方向。 换句话说,机器人“知道”了它的混乱,但是我们在脚本中通过不使用里程表数据,从而不公平地使它变成了残障机器人。 虽然里程表数据不会完全匹配实际运动,但如果使用它,它应该可以为我们提供更好的结果。
    Fortunately, the data we need to correct the problem is staring us right in the face. The large odometry arrows in the image above indicate the robot’s position and orientation as reported by its internal odometry. In other words, the robot “knows” it messed up but we have unfairly handicapped it by not using the odometry data in our script. While the odometry data will not match the real motion exactly, it should give us a better result if we use it.

    展开全文
  • 例如,如果我们发布“Twist”消息以使机器人以0.2 m / s的速度向前移动,我们如何知道该机器人并没有以0.18 m / s的速度前进? 实际上,我们如何知道两个车轮都以相同的速度行驶? When we ask our robot to move ...

    7.7 Are We There Yet? Going the Distance with Odometry (我们到达了吗?用里程表走向远方)

    当我们要求机器人以一定速度运动或旋转时,我们如何知道它实际上在按照我们的要求进行操作? 例如,如果我们发布“Twist”消息以使机器人以0.2 m / s的速度向前移动,我们如何知道该机器人并没有以0.18 m / s的速度前进? 实际上,我们如何知道两个车轮都以相同的速度行驶?
    When we ask our robot to move or rotate at a certain speed, how do we know that it is actually doing what we asked? For example, if we publish a Twist message to move the robot forward at 0.2 m/s, how do we know that the robot isn’t really going 0.18 m/s? In fact, how do we know that both wheels are even traveling at the same speed?

    如本章前面所述,机器人的基本控制器节点使用里程表和PID控制将运动请求转换为真实速度。 此过程的准确性和可靠性取决于机器人的内部传感器,校准过程的准确性以及环境条件。 (例如,某些表面可能会使轮子略微打滑,这会弄乱编码器数量与行进距离之间的映射。)
    As we explained earlier in this chapter, the robot’s base controller node uses odometry and PID control to turn motion requests into real-world velocities. The accuracy and reliability of this process depends on the robot’s internal sensors, the accuracy of the calibration procedure, and environmental conditions. (For example, some surfaces may allow the wheels to slip slightly which will mess up the mapping between encoder counts and distance traveled.)

    可以通过外部测量机器人的位置和/或方向来补充机器人的内部里程计。 例如,可以将壁挂式视觉标记(例如基准)与ROS软件包ar_pose,ar_kinect或ar_track_alvar一起使用,以对房间内的机器人进行相当准确的定位。 类似的技术还有使用视觉特征匹配的方法,而无需人工标记(ccny_rgbd_tools,rgbdslam,RTABMap),还有另外一种软件包(laser_scan_matcher)则使用激光扫描匹配。 除了其他形式的里程表外,室外机器人还经常使用GPS来估计位置。
    The robot’s internal odometry can be supplemented with external measures of the robot’s position and/or orientation. For example, one can use wall-mounted visual markers such as fiducials together with the ROS packages ar_pose , ar_kinect or ar_track_alvar to provide a fairly accurate localization of the robot within a room. A similar technique uses visual feature matching without the need for artificial markers ( ccny_rgbd_tools , rgbdslam , RTABMap ), and yet another package ( laser_scan_matcher ) uses laser scan matching. Outdoor robots often use GPS to estimate position in addition to other forms of odometry.

    为了本书的目的,我们将使用术语“里程表”来表示内部位置数据。 但是,无论如何测量里程,ROS都会提供一种消息类型来存储信息,即nav_msgs / Odometry。 里程表消息类型的缩写定义如下所示:
    For the purposes of this book, we will use the term “odometry” to mean internal position data. However, regardless of how one measures odometry, ROS provides a message type to store the information; namely nav_msgs/Odometry . The abbreviated definition of the Odometry message type is shown below:

    Header header
    string child_frame_id
    geometry_msgs/PoseWithCovariance pose
    geometry_msgs/TwistWithCovariance twist
    

    在这里,我们看到Odometry消息由Header,child_frame_id 字符串和两个二级子消息组成,一个子消息用于PoseWithCovariance,一个子消息用于TwistWithCovariance。【Covariance:协方差】
    Here we see that the Odometry message is composed of a Header , a string identifying the child_frame_id , and two sub-messages, one for PoseWithCovariance and one for TwistWithCovariance .

    要查看定义的扩展版本,请运行以下命令:
    To see the expanded version of the definition, run the command:

    rosmsg show nav_msgs/Odometry
    

    显示如下:
    which should yield the following output:

    Header header
    	uint32 seq
    	time stamp
    	string frame_id
    string child_frame_id
    geometry_msgs/PoseWithCovariance pose
    	geometry_msgs/Pose pose
    		geometry_msgs/Point position
    			float64 x
    			float64 y
    			float64 z
    		geometry_msgs/Quaternion orientation
    			float64 x
    			float64 y
    			float64 z
    			float64 w
    	float64[36] covariance
    geometry_msgs/TwistWithCovariance twist
    	geometry_msgs/Twist twist
    		geometry_msgs/Vector3 linear
    			float64 x
    			float64 y
    			float64 z
    		geometry_msgs/Vector3 angular
    			float64 x
    			float64 y
    			float64 z
    	float64[36] covariance
    

    PoseWithCovariance二级子消息记录了机器人的位置和方向,而TwistWithCovariance组件则为我们提供了线速度和角速度。 pose和twist都可以辅以协方差矩阵,该矩阵可以测量各种测量方法中的不确定度。
    The PoseWithCovariance sub-message records the position and orientation of the robot while the TwistWithCovariance component gives us the linear and angular speeds as we have already seen. Both the pose and twist can be supplemented with a covariance matrix which measures the uncertainty in the various measurements.

    Header和child_frame_id定义了我们用来测量距离和角度的参考坐标系。 它还为每条消息提供了时间戳,因此我们不仅知道我们在哪里,而且在什么时间。 按照惯例,ROS中的里程测量方法使用 /odom作为父坐标系ID,使用 /base_link(或/ base_footprint)作为子坐标系ID。 虽然 /base_link坐标系对应于机器人的实际物理位置,但 /odom坐标系由封装在里程表数据中的平移和旋转定义。 这些转换使机器人相对于 /odom坐标系移动。 如果我们在RViz中显示机器人模型并将fixed frame设置为 /odom坐标系,则机器人的位置反映了机器人认为其相对于其起始位置的位置。(/base_link代表机器人的实际位置,/odom的坐标原点为机器人的起始位置,代表机器人相对于初始位置的移动)
    The Header and child_frame_id define the reference frames we are using to measure distances and angles. It also provides a timestamp for each message so we know not only where we are but when. By convention, odometry measurements in ROS use /odom as the parent frame id and /base_link (or /base_footprint ) as the child frame id. While the /base_link frame corresponds to a real physical part of the robot, the /odom frame is defined by the translations and rotations encapsulated in the odometry data. These transformations move the robot relative to the /odom frame. If we display the robot model in RViz and set the fixed frame to the /odom frame, the robot’s position will reflect where the robot “thinks” it is relative to its starting position.

    展开全文
  • // 有一只青蛙可以在一系列地砖上移动,地砖一面黑色一面白色,青蛙站的地方下面没地砖 // 青蛙有4种移动方法 // 1. 向前走,青蛙和前面的地砖交换位置 // 2. 向后走,青蛙和后面的地砖交换位置 // 3. ...
  • RFC1605_SONET to Sonnet翻译 RFC1606_用IP版本9的历史观 RFC1611_DNS服务器MIB扩展 RFC1612_DNS解析器MIB扩展 RFC1618_ISDN上的PPP(点对点)协议 RFC1628 UPS 管理信息基础 RFC1633_Internet 体系结构中的综合服务...
  • 题解:左右横跳。

    2019-09-29 16:01:09
    分析: 手动模拟之后,我们发现,对于一个数x,他第1次向前移动的格数为2*(n-x)+1;第i次为i=2i-1。也就是说,只有第一次移动的是奇数格。然后,找规律。查询x为奇数时,这个位置的数字是从未移动的。如果是偶数,...
  • Linux 面试

    2020-12-09 11:39:55
    一、处理大文件的日志 ...less与 more 类似,但使用 less 可以随意浏览文件,而 more 仅能向前移动,却不能向后移动,而且 less 在查看之前不会加载整个文件 pageDown向下翻译 pageUp向上翻页 ...
  • Out of Sorts 题解

    2019-03-15 20:03:09
    题面: 翻译: 按照给出的代码,对给定的数据...我们注意到,对于一个排序后位置在原本位置前面的数字,冒泡排序的每一次循环,都会把它向前移动一位. 所以这个题目相当于是要找到排序前后,位置移动幅度最大的数字移动...
  • TopCoder SRM570题解

    千次阅读 2013-02-17 21:26:07
    掉回Div 2了……尼玛…… 依旧是翻译向。...指令包括向前移动x格以及顺时针旋转90*x度。求运行指令T次之后机器人距起始位置的曼哈顿距离。T很大。 分析:先模拟求出运行一次指令后机器人距起始位置的距离d和
  • Xterm下的快捷键

    2009-09-27 22:11:00
    摘自Advanced Bash-Scripting Guide V6.0.05第部分第三...Ctl-A 将光标移到行首Ctl-B 退格键(但是我在ubuntu 9.10 bash 3.2.48上测试却是向前移动光标,并不删除该字符)Ctl-C 中断. 中断一个前台任务Ctl-D 从当前
  • 当摄像机在自动对焦的时候总是有一个困惑,知道图像是不清楚的,但是lens应该向前还是向后移动呢?总是要前后移动lens一下才知道,普通的反差法对焦就是这么做的,爬山嘛。PDAF的出现就是为了解决这个lens移动的问题...
  • Ice Cave

    千次阅读 2019-12-27 11:15:16
    题目链接: ...题面: 翻译: 你玩电脑游戏。你的角色站在一个多层次冰洞的某个层面上。为了向前走,你需要下降一层,唯一的...你可以从每个单元移动到与你相邻的单元(由于游戏引擎的某些限制,你不能在同一个地方...
  • asp.net知识库

    2015-06-18 08:45:45
    理解C#中的委托[翻译] 利用委托机制处理.NET中的异常 与正则表达式相关的几个小工具 你真的了解.NET中的String吗? .NET中的方法及其调用(一) 如何判断ArrayList,Hashtable,SortedList 这类对象是否相等 帮助解决...
  • IETF有观点认为:“IPv6最大的败笔,在于无法向前兼容IPv4协议。”这也是从IPv4升级到IPv6,出现众多演进方案的根本原因。虽然这些方案的技术不外乎三类——双栈、隧道和地址转换,但在不同细枝末节上的变种已超过20...
  • 如何混音处理

    2012-04-25 11:41:21
    关键是中频,先把提升的频点在800Hz-2kHz之间移动,找到那个能引起共鸣的频点,然后调整一下提升的幅度和Q值。对于这种军鼓,往往需要加上启动时间(attack time)较长的压缩、较重的混响来与之配合。 3.钹(cymbal):...
  • 中文版Excel.2007图表宝典 2/2

    热门讨论 2012-04-06 19:01:36
    1.5.1 移动图表和改变图表的大小/17 1.5.2 把内嵌图表转换成图表表单中的图表/18 1.5.3 复制图表/18 1.5.4 删除图表/18 1.5.5 添加图表元素/18 1.5.6 移动和删除图表元素/19 1.5.7 设置图表元素的格式/19 1.5.8 复制...
  • RFC中文文档-txt

    2009-09-11 14:56:56
    RFC1605 SONET to Sonnet翻译 RFC1606 用IP版本9的历史观 RFC1611 DNS服务器MIB扩展 RFC1612 DNS解析器MIB扩展 RFC1618 ISDN上的PPP(点对点)协议 RFC1628 UPS 管理信息基础 RFC1633 Internet 体系结构中的综合服务...
  • 中文版RFC,共456

    2009-04-19 22:56:29
    RFC1605 SONET to Sonnet翻译 RFC1606 用IP版本9的历史观 RFC1611 DNS服务器MIB扩展 RFC1612 DNS解析器MIB扩展 RFC1618 ISDN上的PPP(点对点)协议 RFC1628 UPS 管理信息基础 RFC1633 Internet 体系结构中的综合服务...
  • d 向前删除</li><li>control + h 向后删除</li><li>control + e 到行尾</li><li>control + a 到行首</li><li>control + off(键盘右上角键) 显示重启、休眠、关机等选项</li><li>终端...

空空如也

空空如也

1 2
收藏数 22
精华内容 8
关键字:

向前移动翻译