<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40"><head><meta http-equiv=Content-Type content="text/html; charset=utf-8"><meta name=Generator content="Microsoft Word 15 (filtered medium)"><style><!--
/* Font Definitions */
@font-face
        {font-family:Helvetica;
        panose-1:2 11 5 4 2 2 2 2 2 4;}
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
        {font-family:Consolas;
        panose-1:2 11 6 9 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0in;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
code
        {mso-style-priority:99;
        font-family:"Courier New";}
pre
        {mso-style-priority:99;
        mso-style-link:"HTML Preformatted Char";
        margin:0in;
        margin-bottom:.0001pt;
        font-size:10.0pt;
        font-family:"Courier New";}
p.MsoListParagraph, li.MsoListParagraph, div.MsoListParagraph
        {mso-style-priority:34;
        margin-top:0in;
        margin-right:0in;
        margin-bottom:0in;
        margin-left:.5in;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;}
span.HTMLPreformattedChar
        {mso-style-name:"HTML Preformatted Char";
        mso-style-priority:99;
        mso-style-link:"HTML Preformatted";
        font-family:"Courier New";}
.MsoChpDefault
        {mso-style-type:export-only;}
@page WordSection1
        {size:8.5in 11.0in;
        margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
        {page:WordSection1;}
/* List Definitions */
@list l0
        {mso-list-id:440415202;
        mso-list-type:hybrid;
        mso-list-template-ids:1481513206 -1 67698713 67698715 67698703 67698713 67698715 67698703 67698713 67698715;}
@list l0:level1
        {mso-level-text:"%1\)";
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-.25in;}
@list l0:level2
        {mso-level-number-format:alpha-lower;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-.25in;}
@list l0:level3
        {mso-level-number-format:roman-lower;
        mso-level-tab-stop:none;
        mso-level-number-position:right;
        text-indent:-9.0pt;}
@list l0:level4
        {mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-.25in;}
@list l0:level5
        {mso-level-number-format:alpha-lower;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-.25in;}
@list l0:level6
        {mso-level-number-format:roman-lower;
        mso-level-tab-stop:none;
        mso-level-number-position:right;
        text-indent:-9.0pt;}
@list l0:level7
        {mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-.25in;}
@list l0:level8
        {mso-level-number-format:alpha-lower;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-.25in;}
@list l0:level9
        {mso-level-number-format:roman-lower;
        mso-level-tab-stop:none;
        mso-level-number-position:right;
        text-indent:-9.0pt;}
@list l1
        {mso-list-id:1195969563;
        mso-list-type:hybrid;
        mso-list-template-ids:988828768 -1 67698713 67698715 67698703 67698713 67698715 67698703 67698713 67698715;}
@list l1:level1
        {mso-level-number-format:alpha-lower;
        mso-level-text:"%1\)";
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-.25in;}
@list l1:level2
        {mso-level-number-format:alpha-lower;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-.25in;}
@list l1:level3
        {mso-level-number-format:roman-lower;
        mso-level-tab-stop:none;
        mso-level-number-position:right;
        text-indent:-9.0pt;}
@list l1:level4
        {mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-.25in;}
@list l1:level5
        {mso-level-number-format:alpha-lower;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-.25in;}
@list l1:level6
        {mso-level-number-format:roman-lower;
        mso-level-tab-stop:none;
        mso-level-number-position:right;
        text-indent:-9.0pt;}
@list l1:level7
        {mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-.25in;}
@list l1:level8
        {mso-level-number-format:alpha-lower;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-.25in;}
@list l1:level9
        {mso-level-number-format:roman-lower;
        mso-level-tab-stop:none;
        mso-level-number-position:right;
        text-indent:-9.0pt;}
ol
        {margin-bottom:0in;}
ul
        {margin-bottom:0in;}
--></style></head><body lang=EN-US link=blue vlink="#954F72" style='word-wrap:break-word'><div class=WordSection1><p class=MsoNormal><span style='font-size:12.0pt'>Kumar,<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:12.0pt'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:12.0pt'>What you are looking for is called an “occupancy grid map”.  There are other types of maps, but the occupancy grid map is conceptually the easiest one to understand and work with I believe.<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:12.0pt'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:12.0pt'>Conceptually, its straight forward how it is created.  This type of map is really no different from an image – every pixel corresponds to, for example,  one square inch of space, and the pixel values correspond to definitely empty (black),   definitely something there (white),   unsure (grey).     <o:p></o:p></span></p><p class=MsoNormal><span style='font-size:12.0pt'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:12.0pt'>In a way, it is just an extension of the real-time display code that you have running.  The key differences between real-time display of lidar data and using this data to build a map are:<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:12.0pt'><o:p> </o:p></span></p><ol style='margin-top:0in' start=1 type=a><li class=MsoListParagraph style='margin-left:0in;mso-list:l1 level1 lfo2'><span style='font-size:12.0pt'>For map making, you need to take the robot’s actual current pose (x, y, theta) into account.   (For real-time display, you essentially pretend your robot is always at x,y=0,0  and orientation= 0 degrees)<o:p></o:p></span></li><li class=MsoListParagraph style='margin-left:0in;mso-list:l1 level1 lfo2'><span style='font-size:12.0pt'>For map making, you remember the point that is drawn into the map, instead of starting with a clean canvas every cycle<o:p></o:p></span></li><li class=MsoListParagraph style='margin-left:0in;mso-list:l1 level1 lfo2'><span style='font-size:12.0pt'>For map making, the size of your map needs to be larger than the range of your Lidar, otherwise it won’t be of much use.  <o:p></o:p></span></li></ol><p class=MsoNormal><span style='font-size:12.0pt'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:12.0pt'>You have 3 options:<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:12.0pt'><o:p> </o:p></span></p><ol style='margin-top:0in' start=1 type=1><li class=MsoListParagraph style='margin-left:0in;mso-list:l0 level1 lfo1'><span style='font-size:12.0pt'>Create the algorithm more or less completely from scratch or adapt some sample code that seems to be easy enough to work with.    I’m sure such sample code for python and C++ is out there…. Quick google search found this python code for example:  </span><a href="https://gist.github.com/superjax/33151f018407244cb61402e094099c1d">An occupancy grid mapping example · GitHub</a>.  It says “# This is an implementation of Occupancy Grid Mapping as Presented  in Chapter 9 of "Probabilistic Robotics" By Sebastian Thrun et al.   In particular, this is an implementation of Table 9.1 and 9.2”<br><br><span style='font-size:12.0pt'><o:p></o:p></span></li><li class=MsoListParagraph style='margin-left:0in;mso-list:l0 level1 lfo1'><span style='font-size:12.0pt'>Find a library that contains the necessary building blocks.   Maybe all you need is a ready to use grid map data structure along with an API for putting things into that grid map.   Or maybe the library also provides functions that take care of all the processing of the laser scan data.   Etc, etc.     Then figure out how to use this library.    MRPT comes to mind but there are probably others.   </span><a href="https://www.mrpt.org/">MRPT – Empowering C++ development in robotics</a>.     <a href="https://openslam-org.github.io/">OpenSLAM.org (openslam-org.github.io)</a> is also a possible resource.<br><br><span style='font-size:12.0pt'><o:p></o:p></span></li><li class=MsoListParagraph style='margin-left:0in;mso-list:l0 level1 lfo1'><span style='font-size:12.0pt'>Use ROS and pick one of the mapping algorithms that are available, such as<o:p></o:p></span></li><ol style='margin-top:0in' start=1 type=a><li class=MsoListParagraph style='margin-left:0in;mso-list:l0 level2 lfo1'><span style='font-size:12.0pt'>Gmapping<o:p></o:p></span></li><li class=MsoListParagraph style='margin-left:0in;mso-list:l0 level2 lfo1'><span style='font-size:12.0pt'>Google cartographer<o:p></o:p></span></li><li class=MsoListParagraph style='margin-left:0in;mso-list:l0 level2 lfo1'><span style='font-size:12.0pt'>etc<o:p></o:p></span></li></ol></ol><p class=MsoNormal><span style='font-size:12.0pt'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:12.0pt'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:12.0pt'>I have gone down road # 1 and road # 2 some 5+ years ago, but I did not reach my destination </span><span style='font-size:12.0pt;font-family:"Segoe UI Emoji",sans-serif'>☹</span><span style='font-size:12.0pt'>    I probably didn’t try hard enough…..<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:12.0pt'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:12.0pt'>I have also started going down road #3 on more than one occasion, but find my self often going in circles and not getting anywhere </span><span style='font-size:12.0pt;font-family:"Segoe UI Emoji",sans-serif'>☹</span><span style='font-size:12.0pt'>  <o:p></o:p></span></p><p class=MsoNormal><span style='font-size:12.0pt'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:12.0pt'>I find that no matter which road you take, it requires a substantial time commitment to fully master the underlying technologies.   I find that unless I’m at it every day, I start to forget things I’ve learned….<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:12.0pt'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:12.0pt'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:12.0pt'>Chris.<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:12.0pt'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:12.0pt'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:12.0pt'><o:p> </o:p></span></p><div style='mso-element:para-border-div;border:none;border-top:solid #E1E1E1 1.0pt;padding:3.0pt 0in 0in 0in'><p class=MsoNormal style='border:none;padding:0in'><b>From: </b><a href="mailto:dprglist@lists.dprg.org">Thalanayar Muthukumar via DPRGlist</a><br><b>Sent: </b>Sunday, November 21, 2021 12:36 PM<br><b>To: </b><a href="mailto:dprglist@lists.dprg.org">DPRG</a><br><b>Subject: </b>[Dprglist] Need help with getting a map of the house using RPLidarwith RPi</p></div><p class=MsoNormal><o:p> </o:p></p><div><p class=MsoNormal><a href="https://learn.adafruit.com/slamtec-rplidar-on-pi/cpython-on-raspberry-pi" target="_blank" title="https://learn.adafruit.com/slamtec-rplidar-on-pi/cpython-on-raspberry-pi"><span style='font-size:12.0pt;font-family:"Helvetica",sans-serif;border:none windowtext 1.0pt;padding:0in'>https://learn.adafruit.com/slamtec-rplidar-on-pi/cpython-on-raspberry-pi</span></a><span style='font-size:12.0pt;font-family:"Helvetica",sans-serif;color:#DCDDDE'> -<span style='background:white'> </span></span><span style='font-size:12.0pt;font-family:"Helvetica",sans-serif;color:black;background:white'>The relevant code is below </span><o:p></o:p></p><pre style='vertical-align:baseline'><code><span style='font-family:Consolas;color:black;background:white'>def process_data(data):<o:p></o:p></span></code></pre><pre style='vertical-align:baseline'><code><span style='font-family:Consolas;color:black;background:white'>    global max_distance<o:p></o:p></span></code></pre><pre style='vertical-align:baseline'><code><span style='font-family:Consolas;color:black;background:white'>    lcd.fill((0,0,0))<o:p></o:p></span></code></pre><pre style='vertical-align:baseline'><code><span style='font-family:Consolas;color:black;background:white'>    for angle in range(360):<o:p></o:p></span></code></pre><pre style='vertical-align:baseline'><code><span style='font-family:Consolas;color:black;background:white'>        distance = data[angle]<o:p></o:p></span></code></pre><pre style='vertical-align:baseline'><code><span style='font-family:Consolas;color:black;background:white'>        if distance > 0:                  # ignore initially ungathered data points<o:p></o:p></span></code></pre><pre style='vertical-align:baseline'><code><span style='font-family:Consolas;color:black;background:white'>            max_distance = max([min([5000, distance]), max_distance])<o:p></o:p></span></code></pre><pre style='vertical-align:baseline'><code><span style='font-family:Consolas;color:black;background:white'>            radians = angle * pi / 180.0<o:p></o:p></span></code></pre><pre style='vertical-align:baseline'><code><span style='font-family:Consolas;color:black;background:white'>            x = distance * cos(radians)<o:p></o:p></span></code></pre><pre style='vertical-align:baseline'><code><span style='font-family:Consolas;color:black;background:white'>            y = distance * sin(radians)<o:p></o:p></span></code></pre><pre style='vertical-align:baseline'><code><span style='font-family:Consolas;color:black;background:white'>            point = (160 + int(x / max_distance * 119), 120 + int(y / max_distance * 119))<o:p></o:p></span></code></pre><pre style='vertical-align:baseline'><code><span style='font-family:Consolas;color:black;background:white'>            lcd.set_at(point, pygame.Color(255, 255, 255))<o:p></o:p></span></code></pre><pre style='vertical-align:baseline'><code><span style='font-family:Consolas;color:black;background:white'>    pygame.display.update()</span></code><span style='font-family:Consolas'><o:p></o:p></span></pre></div><p class=MsoNormal><span style='font-size:12.0pt;font-family:"Helvetica",sans-serif;color:black;background:white'>This code is used to update the TFT display and is working for me. Instantaneously, the RPLidar's surroundings are displayed on the TFT display. I would like to adapt this to move the RPLidar through the rooms of the house to create a map. @Chris - Any suggestions or pointers? I do not have ROS installed. Regards. - Kumar </span></p><p class=MsoNormal><o:p> </o:p></p></div></body></html>