I am trying to implement autonomous navigation to my robot and have thus been working on the SLAM gmapping system. However, when I try to visualize the map on Rviz, two things happen: the odom frame switches rapidly between "Transform OK" and "No transform from [odom] to frame [map]" (when the fixed frame is map) and I just see a 400 x 400 black square with pixels of value 100 which should be the map. Here is some more information: This is the file I use to launch everything (lidar_gmapping.launch):

  <!-- Launch SLAM GMapping -->
  <include file="$(find lidar)/launch/slam_gmapping_pr2.launch" />

  <!-- Launch your LiDAR driver -->
  <include file="$(find lidar)/launch/X4.launch" />

  <!-- Launch RViz with the desired configuration -->
  <node name="rviz" pkg="rviz" type="rviz" args="-d $(find lidar)/launch/mapping.rviz" />


    <param name="use_sim_time" value="false"/>
    <node pkg="gmapping" type="slam_gmapping" name="slam_gmapping" output="screen">
      <param name="base_frame"            value="base_footprint"/>
      <param name="odom_frame"            value="odom" />
      <remap from="scan" to="base_scan"/>
      <param name="map_update_interval" value="3.0"/>
      <param name="maxUrange" value="16.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="srr" value="0.1"/>
      <param name="srt" value="0.2"/>
      <param name="str" value="0.1"/>
      <param name="stt" value="0.2"/>
      <param name="linearUpdate" value="1.0"/>
      <param name="angularUpdate" value="0.5"/>
      <param name="temporalUpdate" value="3.0"/>
      <param name="resampleThreshold" value="0.5"/>
      <param name="particles" value="30"/>
      <param name="xmin" value="-50.0"/>
      <param name="ymin" value="-50.0"/>
      <param name="xmax" value="50.0"/>
      <param name="ymax" value="50.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"/>
    <node pkg="map_server" type="map_server" name="map_server" args="$(find lidar)/launch/map.yaml" />
    <node pkg="tf" type="static_transform_publisher" name="map_to_odom"
    args="0 0 0 0 0 0 /map /odom 100" />
    <node pkg="tf" type="static_transform_publisher" name="base_footprint_to_map" args="0 0 0 0 0 0 /base_footprint /map 100" />
    <node pkg="tf" type="static_transform_publisher" name="laser_frame_to_map" args="0 0 0 0 0 0 /laser_frame /map 100" />
    <node pkg="tf" type="static_transform_publisher" name="base_footprint_to_odom"
    args="0 0 0 0 0 0 /base_footprint /odom 100" />


  <node name="ydlidar_lidar_publisher"  pkg="ydlidar_ros_driver"  type="ydlidar_ros_driver_node" output="screen" respawn="false" >
    <!-- string property -->
    <param name="port"         type="string" value="/dev/ydlidar"/>  
    <param name="frame_id"     type="string" value="map"/>
    <param name="ignore_array"     type="string" value=""/>

    <!-- int property -->
    <param name="baudrate"         type="int" value="128000"/>  
    <param name="lidar_type"       type="int" value="1"/>  
    <param name="device_type"         type="int" value="0"/>  
    <param name="sample_rate"         type="int" value="5"/>  
    <param name="abnormal_check_count"         type="int" value="4"/>  

    <!-- bool property -->
    <param name="resolution_fixed"    type="bool"   value="true"/>
    <param name="auto_reconnect"    type="bool"   value="true"/>
    <param name="reversion"    type="bool"   value="false"/>
    <param name="inverted"    type="bool"   value="true"/>
    <param name="isSingleChannel"    type="bool"   value="false"/>
    <param name="intensity"    type="bool"   value="false"/>
    <param name="support_motor_dtr"    type="bool"   value="true"/>
    <param name="invalid_range_is_inf"    type="bool"   value="false"/>
    <param name="point_cloud_preservative"    type="bool"   value="false"/>

    <!-- float property -->
    <param name="angle_min"    type="double" value="-180" />
    <param name="angle_max"    type="double" value="180" />
    <param name="range_min"    type="double" value="0.1" />
    <param name="range_max"    type="double" value="12.0" />
    <!-- frequency is invalid, External PWM control speed -->
    <param name="frequency"    type="double" value="10.0"/>
  <node pkg="tf" type="static_transform_publisher" name="base_footprint_to_laser_frame"
    args="0.0 0.0 0.0 0.0 0.0 0.0 /base_footprint /laser_frame 40" />


  - Class: rviz/Displays
    Help Height: 70
    Name: Displays
    Property Tree Widget:
      Expanded: ~
      Splitter Ratio: 0.5
    Tree Height: 454
  PromptSaveOnExit: true
  toolButtonStyle: 2
Visualization Manager:
  Class: ""
    - Alpha: 0.699999988079071
      Class: rviz/Map
      Color Scheme: map
      Draw Behind: false
      Enabled: true
      Name: Map
      Topic: /map
      Unreliable: false
      Use Timestamp: false
      Value: true
    - Alpha: 0.5
      Cell Size: 1
      Class: rviz/Grid
      Color: 160; 160; 164
      Enabled: true
      Line Style:
        Line Width: 0.029999999329447746
        Value: Lines
      Name: Grid
      Normal Cell Count: 0
        X: 0
        Y: 0
        Z: 0
      Plane: XY
      Plane Cell Count: 10
      Reference Frame: <Fixed Frame>
      Value: true
    - Class: rviz/TF
      Enabled: true
      Filter (blacklist): ""
      Filter (whitelist): ""
      Frame Timeout: 15
        All Enabled: true
          Value: true
          Value: true
          Value: true
          Value: true
      Marker Alpha: 1
      Marker Scale: 1
      Name: TF
      Show Arrows: true
      Show Axes: true
      Show Names: true
      Update Interval: 0
      Value: true
  Enabled: true
  Global Options:
    Background Color: 48; 48; 48
    Default Light: true
    Fixed Frame: map
    Frame Rate: 30
  Name: root
    - Class: rviz/MoveCamera
  Value: true
      Class: rviz/Orbit
      Distance: 14.28176212310791
      Enable Stereo Rendering:
        Stereo Eye Separation: 0.05999999865889549
        Stereo Focal Distance: 1
        Swap Stereo Eyes: false
        Value: false
      Field of View: 0.7853981852531433
      Focal Point:
        X: 0
        Y: 0
        Z: 0
      Focal Shape Fixed Size: true
      Focal Shape Size: 0.05000000074505806
      Invert Z Axis: false
      Name: Current View
      Near Clip Distance: 0.009999999776482582
      Pitch: 0.6503981351852417
      Target Frame: <Fixed Frame>
      Yaw: 1.3453978300094604
    Saved: ~
Window Geometry:
    collapsed: false
  Height: 678
  Hide Left Dock: false
  Hide Right Dock: false
  QMainWindow State: 000000ff00000000fd0000000100000000000001560000024afc0200000001fb000000100044006900730070006c006100790073010000003e0000024a000000ca00ffffff000002c30000024a00000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000
  Width: 1055
  X: 50
  Y: 50


image: map.pgm
resolution: 0.05
origin: [0.0, 0.0, 0.0]
negate: 0
occupied_thresh: 0.5
free_thresh: 0.1

And I created map.pgm by writing

400 400

in a text file. Please someone help me.

  • $\begingroup$ Could you attach a picture of your tf tree through rqt? Also, why would you want your LiDAR measurements be published in the frame map? Normally, laser_frame is used instead $\endgroup$
    – ÁngeLoGa
    Commented Mar 18 at 7:17
  • $\begingroup$ I don't know how to attach images, so I'll describe it here. Actually, the rqt_tf_tree varies between two structures: 1) base_footprint into map with broadcaster /base_footprint_to_map and into laser_frame with broadcaster /base_footprint_to_laser_frame, and then map into odom with broadcaster /slam_gmapping. 2) base_footprint into odom with broadcaster /slam_gmapping, into map with broadcaster /base_footprint_to_map and into laser_frame with broadcaster /base_footprint_to_laser_frame. (So sometimes it's two from base_footprint, with odom coming from map, and sometimes it's three). $\endgroup$ Commented Mar 18 at 17:59
  • $\begingroup$ And don't I need the map frame to use gmapping? $\endgroup$ Commented Mar 18 at 18:01
  • $\begingroup$ You won't be able to publish an image in the comment section. Instead, you normally edit your question with updated information such as the image I asked, or any updates needed. Please look up my answer and try to edit your question with the reply. If you find it clear enough as an answer, please consider to mark it as the answer of your question. $\endgroup$
    – ÁngeLoGa
    Commented Mar 18 at 22:55

2 Answers 2


It turns out that I just had to remove <remap from="scan" to="base_scan"/> from slam_gmapping_pr2.launch. I found out from the fact that rostopic echo /base_scan didn't output anything.


From your last comment, tf tree shouldn't be swapping between two states, it must be uniform if you don't want to have some problems with TFExceptions or other issues.

Normally, you call the start of the tf tree frames from the most parent link (normally "world", "map" or "odom" (depending on your use case)). You can see more in this link, and you would normally call the tfs using the next format: <parent_frame> -> <child_frame>. For example, the base_link -> laser_frame_link is the transformation between the base of your robot and your laser, which is needed for gmapping to work. Knowing that, if you see the information provided in the gmapping wiki (link here) you can see at the end of it which tfs are needed, and which one is provided by the package (please see Sections 4.1.5 and 4.1.6). Bare in mind that in this case, the typo used is <child_frame> -> <parent_frame>, opposed from the one I mentioned previously.

Transformations needed by gmapping

  • <the frame attached to incoming scans> → base_link: This is the transform I mentioned earlier, you need this in order to transform the measurements from the laser, to the local frame.

  • base_link → odom: This is normally published by the controller plugin you are using for your robot, but you could publish it as well. If you read carefully the REP I mentioned earlier you will understand what is the purpose of odom frame.

And gmapping provides the next tf:

  • map → odom: is the estimated pose being calculated by gmapping while performing SLAM.

In any case, in this aspect, you don't need to provide the map -> odom tf since this is being done by gmapping. You are lacking in the parameters provided to the gmapping node the map_frame parameter, but you can see in the wiki that its default value is map, jfyo.

What I was refering in my comment was in your lidar driver launch you are saying that the frame_id used is map. In this term, the measurements done by your lidar would be published as they were measured from the map frame, but in reality, these measurements should be published using the frame where the lidar is defined (normally, lidar_link).

Edit1: Normally you don't create a map just by hand, you run some SLAM package to generate it. When I saw your .pgm I was worried that it wouldn't work. I did tried it in my machine using Ubuntu 18.04 and you would have seen this error in the terminal where you launched the map_server node:

enter image description here

I don't know if the issue here is that you tried to create a static map by hand, or if you just didn't want to have a static map and just work with a local one. You could explain your usecase if needed.

  • $\begingroup$ okay, I've got map to odom to base_footprint to laser_frame and have changed the frame_id to laser_frame, but the map isn't being generated... $\endgroup$ Commented Mar 19 at 17:04
  • $\begingroup$ The issue seems to be the /map topic just outputting 100s as data... $\endgroup$ Commented Mar 19 at 19:08
  • $\begingroup$ Please see my edited answer $\endgroup$
    – ÁngeLoGa
    Commented Mar 20 at 8:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.