<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                # 9.2 Gmapping ## 9.2.1 Gmapping SLAM軟件包 Gmapping算法是目前基于**激光雷達**和**里程計**方案里面比較可靠和成熟的一個算法,它基于粒子濾波,采用RBPF的方法效果穩定,許多基于ROS的機器人都跑的是gmapping_slam。這個軟件包位于ros-perception組織中的[slam_gmapping](https://github.com/ros-perception/slam_gmapping)倉庫中。 其中的`slam_gmapping`是一個metapackage,它依賴了`gmapping`,而算法具體實現都在`gmapping`軟件包中,該軟件包中的`slam_gmapping`程序就是我們在ROS中運行的SLAM節點。如果你感興趣,可以閱讀一下`gmapping`的源代碼。 如果你的ROS安裝的是desktop-full版本,應該默認會帶gmapping。你可以用以下命令來檢測gmapping是否安裝 ```bash apt-cache search ros-$ROS_DISTRO-gmapping ``` 如果提示沒有,可以直接用apt安裝 ```bash sudo apt-get install ros-$ROS_DISTRO-gmapping ``` gmapping在ROS上運行的方法很簡單 ```bash rosrun gmapping slam_gmapping ``` 但由于gmapping算法中需要設置的參數很多,這種啟動單個節點的效率很低。所以往往我們會把gmapping的啟動寫到launch文件中,同時把gmapping需要的一些參數也提前設置好,寫進launch文件或yaml文件。 具體可參考教學軟包中的`slam_sim_demo`中的`gmapping_demo.launch`和`robot_gmapping.launch.xml`文件。 ## 9.2.2 Gmapping SLAM計算圖 gmapping的作用是根據激光雷達和里程計(Odometry)的信息,對環境地圖進行構建,并且對自身狀態進行估計。因此它得輸入應當包括激光雷達和里程計的數據,而輸出應當有自身位置和地圖。 下面我們從計算圖(消息的流向)的角度來看看gmapping算法的實際運行中的結構: ![slam_gmapping](https://img.kancloud.cn/b6/14/b614723cc31fbf7c2f59c9e4916697b0_1832x936.jpg) 位于中心的是我們運行的`slam_gmapping`節點,這個節點負責整個gmapping SLAM的工作。它的輸入需要有兩個: ### 輸入 * `/tf`以及`/tf_static`: 坐標變換,類型為第一代的`tf/tfMessage`或第二代的`tf2_msgs/TFMessage` 其中一定得提供的有兩個tf,一個是`base_frame`與`laser_frame`之間的tf,即機器人底盤和激光雷達之間的變換;一個是`base_frame`與`odom_frame`之間的tf,即底盤和里程計原點之間的坐標變換。`odom_frame`可以理解為里程計原點所在的坐標系。 * `/scan` :激光雷達數據,類型為`sensor_msgs/LaserScan` `/scan`很好理解,Gmapping SLAM所必須的激光雷達數據,而`/tf`是一個比較容易忽視的細節。盡管`/tf`這個Topic聽起來很簡單,但它維護了整個ROS三維世界里的轉換關系,而`slam_gmapping`要從中讀取的數據是`base_frame`與`laser_frame`之間的tf,只有這樣才能夠把周圍障礙物變換到機器人坐標系下,更重要的是`base_frame`與`odom_frame`之間的tf,這個tf反映了里程計(電機的光電碼盤、視覺里程計、IMU)的監測數據,也就是機器人里程計測得走了多少距離,它會把這段變換發布到`odom_frame`和`laser_frame`之間。 因此`slam_gmapping`會從`/tf`中獲得機器人里程計的數據。 ### 輸出 * `/tf`: 主要是輸出`map_frame`和`odom_frame`之間的變換 * `/slam_gmapping/entropy`: `std_msgs/Float64`類型,反映了機器人位姿估計的分散程度 * `/map`: `slam_gmapping`建立的地圖 * `/map_metadata`: 地圖的相關信息 輸出的`/tf`里又一個很重要的信息,就是`map_frame`和`odom_frame`之間的變換,這其實就是對機器人的定位。通過連通`map_frame`和`odom_frame`,這樣`map_frame`與`base_frame`甚至與`laser_frame`都連通了。這樣便實現了機器人在地圖上的定位。 同時,輸出的Topic里還有`/map`,在上一節我們介紹了地圖的類型,在SLAM場景中,地圖是作為SLAM的結果被不斷地更新和發布。 ## 9.2.3 里程計誤差及修正 目前ROS中常用的里程計廣義上包括車輪上的光電碼盤、慣性導航元件(IMU)、視覺里程計,你可以只用其中的一個作為odom,也可以選擇多個進行數據融合,融合結果作為odom。通常來說,實際ROS項目中的里程計會發布兩個Topic: * `/odom`: 類型為`nav_msgs/Odometry`,反映里程計估測的機器人位置、方向、線速度、角速度信息。 * `/tf`: 主要是輸出`odom_frame`和`base_frame`之間的tf。這段tf反映了機器人的位置和方向變換,數值與`/odom`中的相同。 由于以上三種里程計都是對機器人的位姿進行估計,存在著累計誤差,因此當運動時間較長時,`odom_frame`和`base_frame`之間變換的真實值與估計值的誤差會越來越大。你可能會想,能否用激光雷達數據來修正`odom_frame`和`base_frame`的tf。事實上gmapping不是這么做的,里程計估計的是多少,`odom_frame`和`base_frame`的tf就顯示多少,永遠不會去修正這段tf。gmapping的做法是把里程計誤差的修正發布到`map_frame`和`odom_frame`之間的tf上,也就是把誤差補償在了地圖坐標系和里程計原點坐標系之間。通過這種方式來修正定位。 這樣`map_frame`和`base_frame`,甚至和`laser_frame`之間就連通了,實現了機器人在地圖上的定位。 * `/odom` ## 9.2.4 服務 `slam_gmapping`也提供了一個服務: * `/dynamic_map`: 其srv類型為nav_msgs/GetMap,用于獲取當前的地圖。 該srv定義如下: nav_msgs/GetMap.srv ```cpp # Get the map as a nav_msgs/OccupancyGrid --- nav_msgs/OccupancyGrid map ``` 可見該服務的請求為空,即不需要傳入參數,它會直接反饋當前地圖。 ## 9.2.5 參數 `slam_gmapping`需要的參數很多,這里以`slam_sim_demo`教學包中的`gmapping_demo`的參數為例,注釋了一些比較重要的參數,具體請查看`ROS-Academy-for-Beginners/slam_sim_demo/launch/include/robot_gmapping.launch.xml` ```xml <node pkg="gmapping" type="slam_gmapping" name="slam_gmapping" output="screen"> <param name="base_frame" value="$(arg base_frame)"/> <!--底盤坐標系--> <param name="odom_frame" value="$(arg odom_frame)"/> <!--里程計坐標系--> <param name="map_update_interval" value="1.0"/> <!--更新時間(s),每多久更新一次地圖,不是頻率--> <param name="maxUrange" value="20.0"/> <!--激光雷達最大可用距離,在此之外的數據截斷不用--> <param name="maxRange" value="25.0"/> <!--激光雷達最大距離--> <param name="sigma" value="0.05"/> <param name="kernelSize" value="1"/> <param name="lstep" value="0.05"/> <param name="astep" value="0.05"/> <param name="iterations" value="5"/> <param name="lsigma" value="0.075"/> <param name="ogain" value="3.0"/> <param name="lskip" value="0"/> <param name="minimumScore" value="200"/> <param name="srr" value="0.01"/> <param name="srt" value="0.02"/> <param name="str" value="0.01"/> <param name="stt" value="0.02"/> <param name="linearUpdate" value="0.5"/> <param name="angularUpdate" value="0.436"/> <param name="temporalUpdate" value="-1.0"/> <param name="resampleThreshold" value="0.5"/> <param name="particles" value="80"/> <param name="xmin" value="-25.0"/> <param name="ymin" value="-25.0"/> <param name="xmax" value="25.0"/> <param name="ymax" value="25.0"/> <param name="delta" value="0.05"/> <param name="llsamplerange" value="0.01"/> <param name="llsamplestep" value="0.01"/> <param name="lasamplerange" value="0.005"/> <param name="lasamplestep" value="0.005"/> <remap from="scan" to="$(arg scan_topic)"/> </node> ``` ### 演示截圖 gmapping算法演示效果圖如下: ![](https://img.kancloud.cn/9a/a0/9aa042206166482202d2f9baf17073a6_927x898.png)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看