Porting LIDAR-based ‘Find Best Direction’ to Vision-Enhanced Robot

Posted 13 October 2026

While working on my new ‘vision-enhanced’ robot project, it became apparent the the OAK-D Lite camera was not the best tool for handling a ‘stuck’ condition where the robot has nosed into something and needs to find a better movement direction. The camera After some experimentation, I found that by moving the rear-facing VL53L1X LIDAR distance sensor to the front of the robot, I could turn the robot under manual (‘C’) control and watch the reported LIDAR distances change. Since I had already solved the ‘Find Best Direction’ problem on my older robot, I decided to port the code into the new vision-enhanced robot.

Looking back through my old code in C:\Users\Frank\Documents\Arduino\WallE3_Git\WallE3_Git\WallE3_Git.ino, I found a reference to this post. It wasn’t directly relevant as it discussed the problem of sorting multiple arrays in a synchronized fashion so as to arrive at a situation where all the distance and heading sensor arrays are sorted in lockstep with a ‘master’ array containing front distance readings. Then the ‘dependent’ array readings associated with the maximum front distance reading can be easily read off.

This isn’t really necessary for the vision-enhanced robot, as there are only two sensors of interest – the front distances and the associated headings. I believe I should be able to set up two small lists (say 10 elements; front distance readings and associated headings. As the robot rotates, each new distance reading is compared to the stored ones, and replaces the largest value that is smaller than it. The headings array value associated with the replaced heading value gets replaced by the heading value associated with the new distance value. At the end of the rotation, the distance array should contain the 10 highest distance readings, sorted in descending order, and the heading array should be synchronized to their associated distances. Then an ‘appropriate’ heading can be selected from the data (‘appropriate’ to be defined later).

It turns out UpdateIMUHdgValDeg() already manages a HEADING_HISTORY_ARRAY_SIZE array of heading values, where earlier values are bumped up (down in index) and the latest value is stored at gl_HdgHistoryArray[HEADING_HISTORY_ARRAY_SIZE – 1]. If I also have a HEADING_HISTORY_ARRAY_SIZE array of distance values that are handled in the same manner, that should be all I need. I’m pretty sure I already have that array, as that is what is used to calculate variances needed to detect ‘stuck’ conditions. Yep – its there but named ‘aRearDistCM’ instead of ‘aFrontDistCM’. I’ll let that ride until everything is working and then change ‘Rear’ to ‘Front’ everywhere. CalcBruteRearDistArrayVariance() is also there for stuck detection. bool IsStuckBehind() is missing so copied it from WallE3_Git.ino to VisionEnhancedRobot…’. ino (into MISCELLANEOUS section).

Looking back through the code and previous posts, I built up the ‘QuickSort’ algorithms to handle just this situation, so abandoning them for something simpler does not seem real smart; it’s already there, and it works.

Well, maybe not. Looking at WallE3_Git.ino, I see that the RunToDaylight() code does not appear to use QuickSort at all – it does the ‘simpler’ idea of rotating 10 deg at a time, recording both heading and distance. After the rotation I see:

which is pretty much exactly the ‘simpler’ idea I was thinking about.

Well, I may have spoken too soon. WallE3_Git.ino has *two* ‘RunToDaylight()’ functions, ‘RunToDaylight()’ and ‘RunToDaylightV2()’, and ‘RunToDaylight()’ is apparently never called and was replaced by ‘RunToDaylightV2()’ which incorporates the QuickSort algorithms. However, only RunToDaylightV2() Step5:

applies to this situation – all the other code is aimed at finding a trackable wall. Step5 is basically ‘RunToDaylight()’ with the distance and heading arrays presorted by decreasing distance with

I made the decision to port all the ‘RunToDaylightV2()’ and supporting code to the new ‘stuck-recovery’ branch, trimmed down to just the ‘Hdg’ and ‘FrontD’ arrays for now (may later want to add RearD, but not now). This is basically just the ‘Step5’ portion of ‘RunToDaylightV2()’, with the addition of all the supporting code for QuickSort operations.

I have the ‘stuck ahead’ detection running now. Here’s a sample output:

The next step is to use the ‘RunToDaylightV2()’ function and supporting QuickSort code to determine the best direction to travel *after* IsStuck() returns TRUE.

18 October 2026 Update:

After getting the stuck-recovery code working, I created a new C++ project on my PC to parse through the output generated by the 360 degree scans from ‘stuck-recovery’. Here’s the final code:

Including both 36-point (10 deg steps) and a 72-point (5 deg steps) datasets from the ‘stuck-recovery’ code. With the 72-point (5 deg steps) scan data active, the .cpp program produces the following output

Leave a Reply

Your email address will not be published. Required fields are marked *