For nearly ten years, I have been volunteering at a nearby train and trolley museum. I got started helping out by putting some of my electrical engineering background to work, assisting with electromechanical restoration of control systems in old subway and trolley cars preserved in the museum’s collection. As I spent more time at the museum, I became qualified as an operator (or motorman or driver, as different places call the position), I started helping out with maintaining and fixing the overhead line that feeds DC power to our fleet, track repairs, mechanical maintenance and restoration, and various other other priorities at the museum. I even joined the Board of Trustees, putting some of my startup experience to work.

Meanwhile, over a very similar period, I founded and grew a geospatial AI startup called Geopipe, including as cofounder and first engineer building a substantial portion of our technology. We build a product to automatically generate rich digital twins of the real world for gaming, simulation, and architecture, by ingesting raw sensor data about the world and processing it through an “AI” (machine learning and computer vision) pipeline to determine what is in the world, not just how it looks. Among the data we ingested were LiDAR, point clouds created by bouncing a spinning laser off the world and recording a point everywhere it bounces off something, as well as rasters (2D data) and vectors that describe what’s in the world. Naturally, therefore, I’ve always been interested in the idea of building my own LiDAR scanner to collect the type of point cloud data we analyzed at Geopipe.

A perfect opportunity arose the more time I’ve spent volunteering at my museum. We have a variety of careful, specific techniques to measure the track and overhead wire and identify when the track is “out of gauge” (slightly wider or narrower than it should be) or the overhead wire is slightly lower or higher than it should be, but I was curious if a LiDAR scanner could be deployed to collect an overall map of the museum, and at least a rough guestimate of the track gauge and wire height everywhere along the tracks. Keeping this in the back of my mind, I began occasionally looking into LiDAR scanners that were inexpensive, for example aimed at hobby robotics use, that would spin fast enough and have a sufficient range and accuracy to be able to see both the railheads and the wire overhead. I also needed the LiDAR scanner to work outside in at least indirect sunlight.

When I found the STL-27L LiDAR scanner, thanks in no small part to Reddit and especially to the PiLIDAR project, it seemed to fit the bill perfectly. It scans in a 360-degree circle (some scanners only scan a portion of the circle), its range stretches from 3cm to 25m, it scans at 10Hz (although the motor control can drive it at between 6Hz and 13Hz), and its ranging accuracy is quoted at averaging (?) 1.5cm at up to a 2m distance. I had some questions about whether the accuracy was good enough for my application, especially for measuring track gauge where a quarter of an inch (6.4mm) can be the difference between in-gauge track and slightly tight gauge, but it seemed like a good place to start. I also knew that I was going to need to localize the LiDAR points I scanned, and I suspected that simple GPS (GNSS) wouldn’t be accurate enough, especially inside carbarns where the equipment is stored. Research eventually led me to u-blox’s ZED-F9R fused GNSS module, namely the Sparkfun breakout board integrating the unit with an IMU. This module not only does very accurate GNSS positioning, it also does sensor fusion with an Inertial Measurement Unit (IMU), enabling it to very accurately compute position, heading (pose), velocity, and acceleration, including via dead-reckoning when indoors or otherwise GNSS-challenged. It also specifically has models that enable it to improve its accuracy when mounted on cars, scooters, bikes, and as of version 1.40 of the firmware, rail vehicles. With the GNSS module, I can accurately take the plane of points found by the LiDAR scanner and accurately place and pose it in absolute coordinates in the real world. Put all those scans together, and you get a complete 3D point cloud of the entire track and infrastructure at the museum.

To tie it all together, I am using a Raspberry Pi 5 with an SSD for reliability. I previously had a Li-Poly battery-based power supply for my Raspberry Pi 4, but it doesn’t provide enough current to properly power the Raspberry Pi 5. Therefore, after yet more research, I will be using a 20Ah USB battery pack that can push 45W over USB PD paired with a board that converts that to 5V at 5A for the Raspberry Pi. Here’s the hardware testbed with the GNSS board and the LiDAR scanner I’ve been using to build and test the software.


GNSS and LiDAR scanner testbed for museum scanning


Long before I began building software to integrate the GNSS module and the LiDAR points into a cohesive whole, I started by simply communicating with the LiDAR sensor. I used the documentation to write a self-contained C++ library to communicate with the LiDAR scanner. As a test, I used it in a simple program that would collect points over a short period of time, then combine that with a user-supplied, guessed constant speed (e.g., 5mph) to use the timestamps attached to the points to stretch the individual 2D scans, consisting of (y, z, time) points, into 3D (x, y, z) points. Here’s an example of such a (rough) scan, including a great result of the same slie of the interior of the vehicle over and over again, with a not-so-complete view of the outside world, possibly at least partially challenged by reflection or refraction through the window.


https://z80.me/blog/railscan-1/img/lidar_test.png


Next, I have been writing the software to combine the fused GNSS+IMU positions and LiDAR scans into a correct point cloud of the museum. Among other details, this requires:
  • Correctly calibrating the GNSS+IMU to know precisely how it is oriented, including whether it is tilted slightly along any axis.
  • Storing both point cloud files that can be read by other programs as well as information about the trajectory of the LiDAR scanner.
  • Differentiating different runs, including along the same track, that might not be perfectly registered with each other due to GNSS+IMU imprecision.
  • Locating rails and the overhead wire in the point clouds.
  • Correctly handling guard rails, switching tracks, and wire frogs, among other interesting real-world details and occluders.

I have also been working on putting the hardware intro a form appropriate to actually try using to scan real tracks at the museum to test it out. Instead of couplers, trolley cars often have “tow pockets”, into which a metal bar can be slotted using which a locomotive can pull the trolley. One candidate trolley for testing this project has a perfect tow pocket extending out from the body of the car, so that a LiDAR scanner mounted on the end of the pocket will see only the right of way, and none of the structure of the trolley itself. I’ve designed a platform that mounts on the tow pocket that will hold the Raspberry Pi, GNSS board, LiDAR scanner, and a battery for the Pi, and bolts to the tow pocket through the hole for the tow pin. My trusty parts source SendCutSend is fabrication the platform out of plywood, after which I’ll assemble the result and test it out.

Next time, test results and lessons learned from version 1.

Cool stuff!

Quote:
It also specifically has models that enable it to improve its accuracy when mounted on cars, scooters, bikes, and as of version 1.40 of the firmware, rail vehicles


I (admittedly rather quickly) skimmed the documentation and came up empty-handed -- any guesses/observation/knowledge as to what it's actually doing to perform this compensation? How successful is it?
Good question. I haven't run it at all to determine what the fused accuracy is like or how it behaves in different modes, but as best as I can figure, the "dynamic platform models" are used to filter the output of the IMU to reject random noise and jitter and retain what's likely to be relevant (e.g., forward motion, turning within the realistic turning speed and radius of the given vehicle):
Quote:
ZED-F9R supports different dynamic platform models to adjust the high precision sensor fusion navigation engine to the expected application environment. [...] The settings improve the receiver's interpretation of the measurements and thus provide a more accurate position output. Setting the receiver to an unsuitable platform model for the given application environment is likely to result in a loss of receiver performance and position accuracy.
Edit: Now this is a blog post about my progress as well.

I received all the pieces right before July 4th, and assembled my hardware module; a bit over a week ago, I performed the first tests with the LiDAR scanner assembly mounted on a trolley (tram, for our British friends). The setup looks something like this:



In addition to the plywood mount with LiDAR scanner, Raspberry Pi, battery, and GNSS module on the tow pocket, there's also a GNSS antenna mounted on the top of the trolley (in a nondestructive way - zip ties!). Because it's not possible to perfectly level the LiDAR scanner and IMU-containing GNSS module, nor is it possible to ensure they're facing perfectly forward, a part of setting up the system is running two calibration passes. The first measures gravity with the trolley perfectly still to determine any pitch or roll, and the second computes forward (and backwards) acceleration vectors while accelerating or decelerating along a straight track to determine yaw. Unfortunately, I found a bug in the yaw calibration, and didn't have the time to fix it.

A few days ago, after making some changes and fixes to the software, I tried again, successfully performing calibration, and then running the trolley along a U-shaped portion of track that also includes a number of switching tracks, then into a barn. I discovered one obvious bug, that the system flips the perceived angle of the LiDAR-scanned points when the trolley moves backwards, so that points that should be on the left show up on the right, and vice versa: this yields a "ghosting" effect when reversing the vehicle, as points from the same object appear on both sides of the track. I notice some wiggling that I'm not sure the source of: GNSS/IMU imprecision, dead reckoning imprecision, poor vibration damping, or all of the above. I also unfortunately note that the module largely failed to detect the overhead wire, one of the main goals of this project, so I will need to explore if it is possible to mount the assembly higher on one of the trolleys.

I intend to fix the reversal problem and test again on my next visit to the museum, but in the meantime, please enjoy some eye candy! Colors indicate the intensity of the LiDAR returns, including the surprising result that the intensity of the returns differ enough between ballast (roadbed, or gravel) and wooden ties that it may be possible to actually detect the individual ties.




As mentioned in our off-site discussions, those are really neat! I wonder if the next time you run such a test, could you attach a go pro along side, to get irl vs lidar imagery?
Thanks! That would be really cool, not only for the video itself, but also for the possibility of colorizing the point cloud.
KermMartian wrote:
Thanks! That would be really cool, not only for the video itself, but also for the possibility of colorizing the point cloud.


I heard "Dangit TI, don't add to the work load.. But I'll do it"

:p
  
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
Page 1 of 1
» All times are UTC - 5 Hours
 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

 

Advertisement