PDA

View Full Version : [Just For Fun] LIDAR-lite 360 Mirror Scanner



r3n33
06-10-2015, 06:13 PM
This is my idea for using the LIDAR-lite (http://pulsedlight3d.com/) sensor to produce readings in (as close to) a 360 degree view without spinning the sensor itself. I decided to start this project to give some life to my sensor which had never had a real purpose until now.

Thanks to my 3D printer I was able to quickly produce a "rig" to hold the sensor over a mirror. The mirror is attached to a 3D printed plate that is designed to hold the mirror at a 45 degree angle. This will allow me to bend the light 90 degrees from the sensor's emitter. The mirror holder is attached to a stepper motor that will allow me to rotate the sensor's light in a 360 degree view.

Before I go on I've presented a few issues.



Blocking the view. To hold the sensor over the mirror there will be an arm somewhere in the 360 degree view. I've already taken some action here and removed some of the arm material. In fact if I remove too much more the PLA plastic I've used won't be rigid enough to hold the sensor still.





The mirror has to be quite large. This is something I discovered along the way. When it was just an idea in my head the mirror was really small but to ensure both the emitter and receiver are 100% in view I had to use the size you see.





Knowing the mirror position. Because I'm only using a stepper motor for this first design I get no positional feedback. I'll have to assume the mirror position by starting the motor and firmware at a known point.





Reading accuracy. By bending the light alone there is going to be a small offset introduced. Then there is the ever changing distance of the mirror as it rotates. I chose to align the emitter of the sensor to the center of the mirror. This ensures the light will project in a parallel plane. When the light is received it might bounce off the high side of the mirror in one direction and the low side on the other. I may or may not concern myself with such slight offsets introduced in the readings.


So to get back to the setup. I had a NEMA 17 motor collecting dust and a recently purchased Teensy 3.1 (it's pink!) and ordered an a4988 stepper driver from Pololu (black edition to compliment the Teensy). I put everything together today and quickly put some 'duino firmware together. What I'm outputting is the current stepper motor position with the sensor reading. I copied a little bit of the first chunks of data into Excel and it looks like I'm off to a pretty good start.

This project was just for fun but has become pretty interesting. I'd like to make everything available to anyone who is interested so let me know if you need the files now. Once I get things polished up I'll attach the source files here.

The idea:

6019

The creation:

6017

The first results:

6018

There is also a "live" viewer in the works.

6020

And an action shot (thanks Tom)
http://gfycat.com/WholeReliableBlackbuck

tician
06-10-2015, 06:51 PM
More troll ideas...
Another option for holding the sensor over the mirror that might not introduce too much distortion is an acrylic or polycarbonate tube. The only thing to directly obscure the view would be the sensor cable or motor leads depending on which is placed at 'dead' end of the tube. It would also add quite a bit of protection to everything and give the possibility of water-proofing the assembly if the ends are properly sealed. Could also try redesigning the mirror assembly with bushings and a gear system to spin inside the tube so the stepper can be on the same side of the tube as the sensor.

r3n33
06-10-2015, 11:31 PM
More troll ideas...
Another option for holding the sensor over the mirror that might not introduce too much distortion is an acrylic or polycarbonate tube. The only thing to directly obscure the view would be the sensor cable or motor leads depending on which is placed at 'dead' end of the tube. It would also add quite a bit of protection to everything and give the possibility of water-proofing the assembly if the ends are properly sealed. Could also try redesigning the mirror assembly with bushings and a gear system to spin inside the tube so the stepper can be on the same side of the tube as the sensor.

The tube idea is great! I'll have to keep my eyes open for a piece of scrap or something I can repurpose for testing. I did a quick search and found some cast acrylic tubes on eplastics.com for about $40 a foot in a 5" diameter which is just a bit too much for this experiment (for now).

Thanks for the ideas. It's kinda a crazy idea I know but I wanted to see it through.

The live viewer was worked on tonight and here is the result. On the second pass you can see an indention appear around the 200 degree mark. That is me putting the laptop in the way. The 3rd pass I remove the laptop. There is a fine balance of averaging, resolution, and rotation speed that all seem to effect the end result. Anyway here is where it is.


https://www.youtube.com/watch?v=P5O6ZiWnNcU

Zenta
06-11-2015, 08:26 AM
Nice!

Like Tician mention placing both sensor and stepper on same side is a better solution. Using a large thrust bearing holding the tube and a 3d printed gear on the outside of the tube. Could also be used without a tube, just a mirror bracket with a large gear coupled to a bearing system.

Have fun!

KurtEck
06-11-2015, 09:23 AM
Very impressive! Looks like you are having a lot of fun!

this also looks very promising. Sure looks like you find lots of great ideas to use your 3D printer for!

At some point I may have to try to add my Lidar to the Hexapod. My earlier thoughts were to mount it on the same Pan/Tilt as camera. But I would not be able to get 360 degrees (unless the robot moves). Also not sure if it would give the same resolution that you are getting with the stepper motor.

The one idea I had was throw a second lidar on the backside of the turret... But that is probably cheating ;)

r3n33
06-11-2015, 02:41 PM
Nice!

Like Tician mention placing both sensor and stepper on same side is a better solution. Using a large thrust bearing holding the tube and a 3d printed gear on the outside of the tube. Could also be used without a tube, just a mirror bracket with a large gear coupled to a bearing system.

Have fun!

I'll ponder the idea but I think the biggest limitation of all is the sample rate of the sensor. Then again it depends on what sort of resolution the application may need. Because it can scan quite fast but will miss a lot of points along the way. We are playing a little with some ways to keep the rate up and interpolate points. You can see a little of that in the video where the points are altered slightly just after scanning to try and make a best guess as to what might be between the samples.


Very impressive! Looks like you are having a lot of fun!

this also looks very promising. Sure looks like you find lots of great ideas to use your 3D printer for!

At some point I may have to try to add my Lidar to the Hexapod. My earlier thoughts were to mount it on the same Pan/Tilt as camera. But I would not be able to get 360 degrees (unless the robot moves). Also not sure if it would give the same resolution that you are getting with the stepper motor.

The one idea I had was throw a second lidar on the backside of the turret... But that is probably cheating ;)

It could be promising for certain applications. Though the cost could be argued with using something like a continuous rotation servo with position feedback. There is also the option of doing a 180 scan and using two sensor setups. Or even a structured light sensor. Just depends on what you need I suppose. I'm not even sure what I'm going to do with this thing when I'm "finished". Hah, finished ;)

tigakub
06-14-2015, 12:46 AM
This is a fascinating project! I'm really interested to find out how it turns out. Have you considered pointing the sensor upwards, mounting the mirror above it and spinning it with a gear or a belt? Conceivably, you could avoid any obstructions to the beam.

jwatte
06-14-2015, 11:38 AM
you could avoid any obstructions to the beam.

Right -- you'd spin the whole mirror/post setup, using a lazy Susan type bearing (or slip ring.)
Apparently, the "nicer" lazy Susan bearings are called "slew bearings."
Another option (as I suggested in the other thread) is to use the post as the zero marker in the measurements.

r3n33
06-14-2015, 09:13 PM
This is a fascinating project! I'm really interested to find out how it turns out. Have you considered pointing the sensor upwards, mounting the mirror above it and spinning it with a gear or a belt? Conceivably, you could avoid any obstructions to the beam.

Thank you! I have been considering different ways to accomplish this but so far haven't taken action. I like the idea of removing the obstruction but (somewhat embarrassingly) haven't been able to form the image of a simple way to accomplish this. I have a few "half" ideas in my head and probably would benefit from some time at the whiteboard for some drawing or playing in Sketchup.


Right -- you'd spin the whole mirror/post setup, using a lazy Susan type bearing (or slip ring.)
Apparently, the "nicer" lazy Susan bearings are called "slew bearings."
Another option (as I suggested in the other thread) is to use the post as the zero marker in the measurements.

This still is an option I like since I could improve on the design and use a single post rather than a hollowed out post. Being able to home the mirror position is a great solution to not using an encoder or extra hardware which keeps the cost down. Plus I like the overall simplicity of the current design since it doesn't require extra hardware and virtually no assembly.

Spinning the whole mirror/post setup would include spinning the sensor? That's something I wanted to avoid because of the wires.

...

I'll likely try both, using the current design to home the mirror and make a new model that spins the mirror and post.

tigakub
06-15-2015, 04:32 AM
I've actually been knocking this idea around in my head for the past week, too. Here's a crude (really crude) mock up to illustrate what I'm thinking:

6035

Or maybe a belt instead of gears?

tigakub
06-15-2015, 05:01 AM
Right -- you'd spin the whole mirror/post setup, using a lazy Susan type bearing (or slip ring.)
Apparently, the "nicer" lazy Susan bearings are called "slew bearings."

Yes, like this one:

6036

It's a full ceramic bearing, so it should be quite light, and REALLY smooth, with an internal diameter of 60mm which should be plenty wide for the LIDAR Lite. They do tend to get rather pricey, though. This one is US$400. Not really sure how you'd attach anything though. LOL.

I found it here (http://www.vxb.com/page/bearings/PROD/FullCeramicBearings/Kit8331).

r3n33
06-15-2015, 10:44 AM
I've actually been knocking this idea around in my head for the past week, too. Here's a crude (really crude) mock up to illustrate what I'm thinking:

6035

Or maybe a belt instead of gears?

Very nice! Thank you this helps a lot :)

And look what I found.. http://www.trossenrobotics.com/120mm_bearing There is a 140mm version too. Much cheaper than $400 and has the ability to attach a mirror pretty easily. I think I'm going to order one today! :: Ordered :)

tigakub
06-15-2015, 02:49 PM
Very nice! Thank you this helps a lot :)

And look what I found.. http://www.trossenrobotics.com/120mm_bearing There is a 140mm version too. Much cheaper than $400 and has the ability to attach a mirror pretty easily. I think I'm going to order one today! :: Ordered :)

Excellent! I didn't think to look closer to home. Lol, I want one now.

r3n33
06-15-2015, 03:09 PM
Excellent! I didn't think to look closer to home. Lol, I want one now.

Neither did I but google is my friend and put the Trossen result nice and close to the top for me =) After doing a little modeling of your suggestion I decided to get the 140mm version. There were not a lot of dimension/specifications given on the bearing so I wanted to play it safe. I didn't want to end up with something too small that I couldn't use.

r3n33
06-21-2015, 12:43 AM
Well thanks to everyone's input I've put together "model B" and I'm really happy with the results. I wasn't going for looks here.. Just wanted a quick test. The base isn't as sturdy as I'd like and doesn't house the electronics or anything fancy. Yet?
I used the 140mm bearing from Trossen and reused the motor and mirror. The mirror holder used was the quickest thing I could model because I was anxious to start testing and just holds the mirror with (strong) double sided tape.

Thanks again everybody for the help :cool:

So here is the model as it turnd out:

6052

The printed and assembled parts (slightly different looks [taller base posts, upside down gear] due to revised parts):

6053

And here is a video of it in action doing a pretty fast scan:


https://www.youtube.com/watch?v=OjREfE2-rJg

KevinO
06-21-2015, 12:46 AM
That is awesome. Totally awesome.

KurtEck
06-21-2015, 07:49 AM
Looks great. It is amazing how quickly you an take an idea like that and come up with a working version!

Zenta
06-21-2015, 09:11 AM
That's more like it! Great work, I'm also impressed of your skills and your fast prototyping.
Awesome!

jwatte
06-21-2015, 02:22 PM
A belt has less backlash but more risk of slip. Seems easier to get to run smoothly and quietly, though.

r3n33
06-21-2015, 02:23 PM
Thank you, thank you, and thank you :D

Once I had the picture in my mind putting together the parts was a fairly easy process. Regardless of the relative difficulty of the tasks such praise from you all is very much appreciated. This was a fun mini-project that taught me a few things along the way and resulted in a base system in which I can perform experiments. There are some little things I'd like to do to improve the design but I'm not expecting to have to disassemble mine any time soon so if anyone wants the 3D models or Sketchup source let me know please.

Now I'm off to figure out what I'll do with this thing plus play with scan rates, different ranges, data smoothing, considering ROS ;), etc.

tigakub
06-21-2015, 05:59 PM
OMG, that's superb! It's incredible to see it in action!

r3n33
06-22-2015, 11:13 AM
A belt has less backlash but more risk of slip. Seems easier to get to run smoothly and quietly, though.

Ah yes. A belt would be nice because it is a little noisy. I was able to reduce the noise a great deal by adjusting the current potentiometer. Changing the rotation speed actually helps keep the resonation down a bit. I created the gears myself so I'm assuming a good gear generator will also help the situation.


OMG, that's superb! It's incredible to see it in action!

Hah! Thank you! I've gotten the scan rate down to 2-3 seconds per rotation while still being able to see things like my head and arms in the air in one pass. Moving away from the Teensy (https://forum.pjrc.com/threads/28036-Translating-Lidar-Lite-I2C-example-to-Teensy) helped a lot because I couldn't get the readings faster than 40ms over I2C in the time I'm willing to spend on this. Sorry pink teensy.. till another time.

So I switched to a Mega clone that has no trouble reading at 15ms (currently). I hacked up a SparkFun audio shield that they sent me a bunch of in some of those grab bag boxes. Turns out it did come in handy for something =) Now I removed the breadboard and added a socket to plug in a motor driver. Everything is a little more secure for prototyping now and that makes me happy :D

6057

Now since I'm really starting to like the results I plan to improve the base of the design. Here I'm thinking support the entire bearing (two posts are missing) and I'll likely make the posts separate printable parts to speed up the printing time. Also gives you the ability to use other standoffs to vary the height of the mirror depending on the height of the motor used. I'd also like to be able to fasten the motor because currently it sits a couple mm in a perfectly sized cutout and increase the overall strength of the base since the first pass I try to waste as little time and plastic as possible.

Finding a good gear generator will also be on the todo list as well as making a more secure mirror holding bracket. I'm open to suggestions and if there is anything anyone would like to see tested let me know please.

tician
06-22-2015, 11:45 AM
A belt has less backlash but more risk of slip. Seems easier to get to run smoothly and quietly, though.
A properly sized and tensioned timing belt should never slip, and mcmaster sells MXL and XL belts (http://www.mcmaster.com/#timing-belts) in many sizes for a few dollars each. Their pulleys can be a bit more expensive at $7~15, but I expect there are programs out there to generate the correct trapezoidal profile given the popularity of timing belts in 3D printers.

There was a rather nice looking gear generator linked in this thread (http://forums.trossenrobotics.com/showthread.php?7501-Using-AX-12A-in-zero-torque-mode) not too long ago. edit: the most common pressure angle used to be 14.5 degrees, but has been a general shift to 20 degrees for heavier load handling. Since they are custom printed and unlikely to interact with 'standard' gears and there is not much of a load it should not really matter much what parameters are used.

KurtEck
06-22-2015, 01:38 PM
Again Great Work!

Still wondering what is going on with the Teensy... I know you should be able to do very high speed I2C communications with it, so wondering about what is causing this... Maybe I should hook mine up :D

Kurt

r3n33
06-22-2015, 02:22 PM
A properly sized and tensioned timing belt should never slip, and mcmaster sells MXL and XL belts (http://www.mcmaster.com/#timing-belts) in many sizes for a few dollars each. Their pulleys can be a bit more expensive at $7~15, but I expect there are programs out there to generate the correct trapezoidal profile given the popularity of timing belts in 3D printers.

There was a rather nice looking gear generator linked in this thread (http://forums.trossenrobotics.com/showthread.php?7501-Using-AX-12A-in-zero-torque-mode) not too long ago. edit: the most common pressure angle used to be 14.5 degrees, but has been a general shift to 20 degrees for heavier load handling. Since they are custom printed and unlikely to interact with 'standard' gears and there is not much of a load it should not really matter much what parameters are used.

I do believe they were set at a 2:1 ratio with about a 25 degree angle. I made the pinion gear a size that looked decent for the number of teeth but I don't recall the diameter. That was the gear generator I remember seeing and I tried to use that at first but was given too much grief when attempting to bring the generated files into the model. Actually my first attempt at printing the gears I made them look like what was generated on that website and it would turn fine by hand the motor wasn't strong enough. Then I doubled the number of teeth and changed the angle and I have what was shown.

I think a belt is going to be the way to go. It should be smoother and nearly silent. Thanks for the link.


Again Great Work!

Still wondering what is going on with the Teensy... I know you should be able to do very high speed I2C communications with it, so wondering about what is causing this... Maybe I should hook mine up :D

Kurt

Thanks. Me too. The Teensy should be perfectly capable. I skimmed though all those pages a couple times and tried their examples. There was only one that seemed to read continuously but if you added the delay of formatting and sending an output string it would eventually hang. I probably sat down with it 3 or 4 times trying to adjust what I thought should work and felt silly when I'd see mega doing nothing so I made the switch.

tician
06-22-2015, 03:44 PM
A word of warning about McMaster-Carr: their warehouses are essentially UPS shipping/distribution centers. This means most things are shipped same day as ordered but also means UPS ground is the cheapest option they offer, so small and inexpensive (<$20) orders are not recommended. Fortunately, there are all sorts of goodies in their catalog (I've lost many hours wandering through it), so finding things to pad out the order to make it worth the shipping cost is usually pretty easy.

r3n33
06-22-2015, 04:16 PM
Haha.. Warning. Lot's of shopping. Don't spend all the money. :p

KurtEck
06-22-2015, 06:14 PM
Thanks. Me too. The Teensy should be perfectly capable. I skimmed though all those pages a couple times and tried their examples. There was only one that seemed to read continuously but if you added the delay of formatting and sending an output string it would eventually hang. I probably sat down with it 3 or 4 times trying to adjust what I thought should work and felt silly when I'd see mega doing nothing so I made the switch.
I looked at those pages as well and was hoping that Paul would have a solution for it... Again sounds like a fun thing to look at...

Watch it turn it that the Lidar simply does not like 3.3v signals... Maybe I will grab one of my Seeedstudio megas with one of my breakout boards and see what the signals look like...

Kurt

Edit: I currently have Paul't test program in posting 89 (https://forum.pjrc.com/threads/28036-Translating-Lidar-Lite-I2C-example-to-Teensy?p=70214&viewfull=1#post70214) and I am running it on a purple Teensy 3.1 using Arduino 1.6.5r2 with Teensyduino 1.24 beta 3 which appears to have Pauls updated Wire.cpp file (used winmerge to compare the file he had in posting to one installed by Teensyduino). So far maybe 30 minutes in no hangs average time probably 10 millis...

jwatte
06-22-2015, 06:35 PM
finding things to pad out the order to make it worth the shipping cost is usually pretty easy

I used to think like that, but then I realized that an order for a $3 box of screws and $7 shipping actually costs me less dollars than an order for a $3 box of screws, $7 shipping, and $28 of other miscellaneous stuff that I might not ever get around to actually using...

That being said, if Small Parts has that same box for $4, free Prime shipping makes that the better choice. Small Parts are hit-or-miss on what's in stock, though.

r3n33
06-23-2015, 10:33 PM
So for good practice I decided to take a crack at bringing this home made scanner into ROS. At first I thought I could emulate the Neato XV-11 protocol but when I got knee deep in code I realized it wasn't going to work out as well as I had hoped. So instead a pretty crude ROS node was born that handles the data the way I'd like to output from my scanner.

Here is the first signs of life from the Lidar scanner in ROS! Weeeee! Can't wait to see what else it can do.

6060

jwatte
06-24-2015, 10:48 AM
Sounds like you're well served by the ROS architecture!

r3n33
06-25-2015, 08:54 AM
Ah yes most definitely!

I've tweaked my 3D model a bit and I'm pretty happy with where it is now so I'll likely release the 3D files soon.

6069

I realize the first sign of life from ROS needed a bit of improvement and at the moment I'm contesting with some faulty readings ( sensor RMA in process ) but when the sensor is cool the accuracy looks pretty good. So this is the best video of the ROS visualization I can share for now. When my new sensor arrives I'll be able to experiment more and we'll see what may come!


https://www.youtube.com/watch?v=ihf8LnleXzE

birdman
06-29-2015, 07:52 PM
Two quick questions:
1. Any thoughts yet on adding a 2nd axis?
2. Any thoughts on a pop-up (or blade-style, just turn edge on to make it dissapear) or fixed (yeah, causes the same narrow angle blockage) body-mounted reference pin? (Deployed up into the FOV)...multiple scans would allow very good centroiding, and it would allow a true closed loop periodic realignment between the body axis and the scanner position. That way, you could lighten-up the control code for the stepper, potentially run it faster without any accumulated angle errors due to gear tolerance or external influences (slip, rotation when not on, etc) and allow self-calibration. Just a thin metal blade (with retroreflective film if needed) that gets flipped perpendicular to the beam when you want to calibrate...you could even actuate it with a small SMA wire to really make it unobtrusive /lightweight.

r3n33
06-29-2015, 10:40 PM
Actually no to both of those :)

I think number two is interesting and while pondering the idea I thought about the use of a magnet and a reed switch. This way nothing has to obstruct the view and nothing has to be actuated. While I'm waiting for my replacement sensor I think I'll investigate more. Thanks for the idea boost!

birdman
06-30-2015, 07:41 AM
Actually no to both of those :)

I think number two is interesting and while pondering the idea I thought about the use of a magnet and a reed switch. This way nothing has to obstruct the view and nothing has to be actuated. While I'm waiting for my replacement sensor I think I'll investigate more. Thanks for the idea boost!

Problem with sensing the gear rather than the actual optical surface is you can't percieve misalignment. Think of it this way, the angle you care about and want to know is the rotational angle of the mirror w.r.t. The body, not the gear, not the motor. The mirror directs the beam, so by sensing the beam position (in this case, by having a "known" part of the body be able to be sensed) you eliminate any possible errors in misalignment, etc.
a hall type sensor on the gear is still interpreted--mirror to gear misalignments can't be sensed.

Also, by using the sensor itself as the calibration source, you also don't need any additional inputs/code local. You just need a single, very rarely used DIO to flip the blade, and then your normal sensor becomes its own calibrator. Low frequency DO >>> high fidelity AI w.r.t. Component utilization and code requirements.

(just my thought on what lead me down the path...the hall/magnet is also good in a few ways as well, unobtrusive, cheap, doesn't require activation, etc...if your mirror to gear alignment is stable, then it's good)

birdman
06-30-2015, 08:35 AM
Also, with a blade of a very known width, you should be able to not only centroid it to well < a step size on your stepper, but also get enough steps across it to get statistics on step size over time to account for gear wear, etc. basically, it's the difference between measurement and dead reconning--a known object in body space measured by the sensor is closed loop calibration (all errors from sensor back to body are addressed), while something measuring not the actual optical axis, with a different sensor is effectively only one step better than dead reconning on the motor steps, it can only remove errors that occur between it and the drive.

You ou coukd do it with a fixed pin, giving up some part of your FOV for calibration is industry standard (dark/white rows on a CCD, internal cal lamps / retro reflectors on FLIR/laser turrets, etc. ideally you always want to calibrate a sensor with itself, as that removes the maximum number of error sources.

birdman
06-30-2015, 08:42 AM
Also, if you used a tapering blade, you could actually measure both axes, or in the current one-axis rotation, determine any elevation changes (by measuring both the centroid and width)

and nd any thoughts to lateral mirror supports? Withh he gear setup you have, you coukd make a whole 3-sided box for the mirror. Would add stability and reduce stray light. You could print it as a second part, that would then bolt to the same bolts as the gear to bearing...also, that way the mirror-to-gear alignment is on the bolts, not part of the print.

sorry for all the posts...I'm likely going to build a version of this myself in the next few weeks, so I'm thinking a lot about it.

jwatte
06-30-2015, 10:50 AM
step size over time to account for gear wear

Step size doesn't change over time with wear. For this kind of assembly, backlash will increase with wear, but nothing else in the formula changes.

If the gear has a known, integer ratio to the body (such as 1:1) then a hall effect or optical sensor on the gear is almost exactly the same as a field-of-view pin along the axes of concern (registration, robustness, etc.)
Yes, you need to express the relation between the sensor and the mirror-body-forward -- but this is no different than expressing the relation between the pin and body-forward. It's a single quantity, that you measure (or hard-code) once.

birdman
06-30-2015, 12:02 PM
Not quite, you have three error sources, sensor to body, magnet to sensor, mirror to magnet. The only one you measure in the hall case is magnet to sensor, the rest are assumed to be small (and unmeasured) By measuring a body element with the sensor, you have one combined error source, mirror to body, and that is directly measured. Yeah, it probably doesn't make much of a difference, but having a small occultation (if fixed) with a tapered element minimizes unmeasured or characterized error sources and also gives you a vertical (elevation) alignment--you now can directly measure in the sensor frame the elevation angle of the measurement path--since it is then based solely on taper profile (doesn't change and can be measured extremely precisely) and distance to optical/rotation axis (can be measured to great accuracy and fixed).

dont worry, I'm not criticizing your solution (an ideal system would use both, the hall for continuous readout/on the fly cal, and the blade for periodic recalibration/elevation compensation), just suggesting a calibration method that eliminates unmeasured/U characterized errors and potentially gives you greater precision...likely not needed, but a thought to keep in mind, especially if you add a second axis, as the tapered blade would allow you to characterize the full covariance matrix of the two axes (and also, if you had two axes, you could then use a fixed blade that was out of the normal useful FOR)

jwatte
06-30-2015, 02:57 PM
The calibration is the same in both cases. If you think that the magnet will slip, the sensor will slip, the gears will slip, or the mirror will slip, then I'd argue that the most likely cause of that would be catastrophic failure, when neither solution will work very well!

If you use frequently slipping mounts (like clamps or whatever) then there's more chance that things might go out of alignment after calibration, but why would you do that when through holes and lock nuts are so easy? :-)

birdman
06-30-2015, 04:59 PM
Sorry, I think we are talking past each other. Let me clarify. Let's say you have a 200 step/rotation motor, a 4:1 gear ratio, and a best case of 1/4 step microstepping, and the mirror is 50mm across, mounted on a 120mm diameter bearing, with the magnet on edge of a 140mm diameter large gear.
your step size is effectively 1/(4*4*200) of a circle, or 1.9mrad. If my blade idea is 100mm from the laser, is 20mm wide, and is mounted to the body with a generic precision of 0.4mm (same with the rotational axis of the mirror, or any other part, like magnet or sensor) and is stable to 0.1mm over time.
that means I have ~100 microsteps across the blade, and I should be able to easily localize it in angle space to better than its mounting precision, meaning I've now localized the beam in angle space relative to the body axis to -at least- (sqrt(2)*0.4) /100 or <6mrad or better, with a stability of 1-2 mrad over time.

with the magnet approach, the best body to sensor accuracy is 0.4/70 or ~5mrad, the magnet to gear is the same (~5mrad), and the mirror to gear is (sqrt(2)*0.4)/50 in angle space, or ~11mrad (stability of 1.25, 1.25, and 2.75 mrad respectively)
assuming uncorrelated errors, this means an accuracy of no better than sqrt(5^2 * 5^2 * 11^2) or 13mrad, with a precision of ~3mrad.

so the -best- the magnet can do is ~2x worse (note, moving the blade further away will improve performance, while the magnet can't be moved any further away) and its errors aren't that small, 3mrad is 2x the microstep size, or half a real step, while the optical is better than a microstep size. A 10mm blade @ 100mm away is only a ~6 deg blockage, and can easily be dealt with if non-deployable. since there is 100 microsteps across the blade, let's say it's 100mm tall, and tapers from 5-10mm, with a measurable width precision of ~0.2mm, that means you could localize the center of the beam in elevation space to about 1/25th of the height, or ~20mrad with a single pass, and with multiple passes, even better.

The he big thing is it has fewer tolerances elements. Since the beam is doing the measuring, the mirror to gear alignment (2 uncorrelated tolerances) doesn't matter, neither does magnet to gear, and sensor to body and thus it's only two (rotational axis to body, blade to body) rather than 4. The additional radius of the blade further improves the angle precision for a given lateral tolerance.

So all im saying is it bymathematical definition (all mounting tolerances held constant for any element, and it has fewer elements, 2 (rotational axis tolerance and blade tolearn easy) vs 5 technically) is more accurate and precise, and if you are willing to accept a small occlusion (ie non deployable) requires zero hardware other than a cut piece of shim stock or rectangular tube. If you want it deployable, a simple solinoid could turn the blade and it would cause no occultation.

anyway, that's all I was thinking. It's a level of precision and accuracy not likely required, but on the other hand, it technically can be done without any additional active hardware, or with minor if you want to avoid any occultation.

jwatte
06-30-2015, 06:15 PM
Gotcha. My assumption is that with 200x4:1 steps and 4 microsteps, the precision of a hall sensor (16000:1) is better that the precision of your step (3200 steps, 16000 sensor precision, typically the upper range of magnet or absolute optical sensors)
Couple that with the actual read timing of the sensor, and the scan and data rate you'll want to use for moving localization, and the precision of either sensor is not the limiting factor.

Now, as for the uncorrelated errors, I think that once everything's fixed in position, there will be very little drift (much less than your assumptions.) So, a single calibration on day 1 might be enough to make either kind of sensor be better than the other limiting factors.

Whether things will stay still is then more a construction question than a precision question. Note that I proposed using the holding beam as the zero reference a while back in the thread (when the construction was spinning from above,) so from a practical point of view, I actually think it's an elegant (and cost effective) solution! (I'd also want the beam to be narrower than 100 microsteps!)

birdman
06-30-2015, 06:44 PM
I still somewhat disagree with that calculation (the precision has nothing to do with the step size in either case, but rather the mounting precision/stability), but that's a discussion for another time. Anyone else get what I'm saying that possibly could explain more clearly?

Overall, you are correct, either method is more precise than needed.

I did want to show what even minor (0.004" jitter in mounted stuff is quite reasoble for these kinds of structures/bolts, and 0.01-0.02" mounting error is probably better than expected...I was actually giving it the benefit of the doubt.

but as real world example, take some -really- precise encoders (like 10's of k each), and some -unbelievably precise- IMUs (think what you could buy for a few hundred k) that are packaged in a several million dollar sensor turret that hangs on a really big drone, using the sensor itself to measure alignment items is way more accurate than any of the internal measurements and calibrations....for all the reasons / math I used above, and the same principles apply. Direct measurement of errors and bias in a sensor frame will always yield better results.

Note: the actual beam width in microsteps doesn't matter, it just needs to be wide enough at its distance to provide a return, preferably multiple steps wide to allow for adequate centroiding.

jwatte
06-30-2015, 10:38 PM
Direct measurement of errors and bias in a sensor frame will always yield better results.

Got it!
My real point was this:


either method is more precise than needed

Then, the non-blocking option may be more desirable because of this:


the actual beam width in microsteps doesn't matter

Except if you want to measure what's right behind it, which I believe was the reason to go to the mirror suspended from below in the first place.

I actually don't disagree with your math. You did the math better than me.
I disagree that the purported outcome ("using a beam is better") actually follows from the problem statement. Put another way: It's not better along an axis that seems to matter.

Sorry to beat this dead horse. I agree that your error calculations are correct for the quite reasonable assumptions you state.

Hopefully r3n33 will come back with more pictures about what the next step actually is :-)

r3n33
07-06-2015, 08:22 AM
Hopefully r3n33 will come back with more pictures about what the next step actually is :-)

Hah! No Pressure right? :)

Well I'm still in no way finished with this little project but I'm mainly waiting for a replacement sensor. According to UPS PulsedLite should received the broken sensor today so hopefully not too much longer.

In the mean time I've discovered they are releasing a new model. http://pulsedlight3d.com/products/lidar-lite-v2-blue-label

The new version will be really nice on something like a scanner with 500Hz update! It still doesn't quite come close to the performance of the TeraRanger One (http://www.teraranger.com/products/teraranger-one/) but it's from a company I have just a tiny bit more experience with. The new version of the Lidar Lite also mentions they've improved the I2C communication so maybe my Teensy can come back out to play without giving me a headache.

KurtEck
07-06-2015, 08:54 AM
Both of those look like fun! Thought of pre-ordering a V2, but it more or less said there are no shipping methods to my address???

The TeraRanger looks really nice especially since already ROS, plus can connect by USB or Serial.

As for Teensy, I do have my Lidar V1 hooked up to one, let me know if you have some code to try out to see if it is working...

Kurt

r3n33
07-06-2015, 10:32 AM
Really? No shipping methods? I've almost pre-ordered that thing 3 times this morning. My hesitation is the price since I'm waiting to feel like I got my $89 worth from the first one and I believe if they were smart I'd have a pre-release unit on my desk already ;) Hint hint?

The TeraRanger does look really nice and although ROS isn't hard to incorporate the USB feature can be great to help reduce the space requirements. If you look closely there is a big difference in range specifications but I have no idea how well they actually compare side by side. Also I think the price to have a TRone shipped to the US was around $180.

I still have my original Teensy code from the first revision but it was mainly taken from the examples on the Teensy troubleshooting page. Perhaps I was having extra trouble because there was something else wrong with my sensor (very bad readings when warm). I can give you the code if you really want it but I won't be available to debug the issue any further.



#include <Wire.h>
// forum.pjrc.com/threads/28036-Translating-Lidar-Lite-I2C-example-to-Teensy

#define LIDARLite_ADDRESS 0x62 // Default I2C Address of LIDAR-Lite.
#define RegisterMeasure 0x00 // Register to write to initiate ranging.
#define MeasureValue 0x04 // Value to initiate ranging.
#define RegisterHighLowB 0x8f // Register to get both High and Low bytes in 1 call.

#define DELAY_USEC 50

int reading = 0;
long dT;
long tNew, tOld; // time in milliseconds()

int pin_led = 13;
int pin_step = 3;
int pin_dir = 4;

IntervalTimer myTimer;
volatile int motorStepCnt = 0;
int stepsPerRevolution = 1599;
void stepmotor( void )
{
digitalWrite(pin_step, HIGH);
if ( ++motorStepCnt > stepsPerRevolution )
{
motorStepCnt = 0;
}
digitalWrite(pin_step, LOW);
}

void setup( void )
{
Wire.begin();
Serial.begin(115200);
while (!Serial) ;
delay(10);
//Serial.println("LIDAR Test");
tOld = millis();

pinMode(pin_led, OUTPUT);
pinMode(pin_step, OUTPUT);
pinMode(pin_dir, OUTPUT);
digitalWrite(pin_dir,LOW); //CCW Motor turns main gear CW

myTimer.begin(stepmotor, 1800);
}

float motorPos;
void loop( void )
{
int r;

while (1)
{
Wire.beginTransmission(LIDARLite_ADDRESS);
Wire.write(RegisterMeasure);
Wire.write(MeasureValue);
r = Wire.endTransmission();
if (r == 0) break;
delayMicroseconds(DELAY_USEC);
}

while (1)
{
Wire.beginTransmission((int)LIDARLite_ADDRESS);
Wire.write((int)RegisterHighLowB);
r = Wire.endTransmission();
if (r == 0) break;
delayMicroseconds(DELAY_USEC);
}

while (1)
{
r = Wire.requestFrom((int)LIDARLite_ADDRESS, 2);
if (r > 0) break;
delayMicroseconds(DELAY_USEC);
}

if (Wire.available() >= 2)
{
reading = Wire.read() * 256;
reading |= Wire.read();
tNew = millis();
dT = (tNew - tOld);
if ( reading < 1024 && reading > 0 )
{
noInterrupts();
motorPos = (360.0 / stepsPerRevolution) * motorStepCnt;
interrupts();

Serial.print( motorPos );
Serial.print(",");
Serial.print(reading);
Serial.print(",");
Serial.print(dT);
Serial.println();
}
tOld=tNew;
}

// lidar lite reported to give wrong results without this delay
delayMicroseconds(100); //Started at 100
}

jwatte
07-06-2015, 10:34 AM
TeraRanger looks interesting. Also looks like they're shipping 3D printed enclosures -- in this market, they should just ship the STL files and be done with it :-)

Neither of these options get to the speed of the Neato LIDAR though, and you have to build your own rotation. Which I guess is half the fun :-)

r3n33
07-06-2015, 10:52 AM
Yeah I agree about the 3D printed bracket/case those are cute but at least an STL would be much more useful to many of us. Plus I consider my 3D printed parts prototypes; if plastic parts are to be part of an end user product I'd like for them to be put together a little better.

What is the acquisition rate of those XV-11's anyway? I've seen they rotate up to 300 rpm and I seem to recall they output a reading every degree. I think if the LidarLite does produce accurate readings at 500Hz we can get close to a 2Hz update rate if I can make the mirror spin fast enough. Likely easier with my original idea where the mirror is directly connected to the motor.

KurtEck
07-06-2015, 11:33 AM
Thanks, I will take a look at what you posted and compare it to the one I was playing with:

#include <Wire.h>
// forum.pjrc.com/threads/28036-Translating-Lidar-Lite-I2C-example-to-Teensy

#define LIDARLite_ADDRESS 0x62 // Default I2C Address of LIDAR-Lite.
#define RegisterMeasure 0x00 // Register to write to initiate ranging.
#define MeasureValue 0x04 // Value to initiate ranging.
#define RegisterHighLowB 0x8f // Register to get both High and Low bytes in 1 call.

int reading = 0;
long dT; // difference in time between readings
long tNew, tOld; // time in milliseconds()

void setup()
{
Wire.begin(); // basic I2C library
Serial.begin(115200); // start serial communication at 9600bps
while (!Serial) ;
delay(10);
Serial.println("LIDAR Test");
tOld = millis();
}

#define DELAY_USEC 50

void loop()
{
int r;

while (1) {
//Serial.print('*');
//Serial.flush();
Wire.beginTransmission(LIDARLite_ADDRESS); // transmit to LIDAR-Lite
Wire.write(RegisterMeasure);
Wire.write(MeasureValue);
r = Wire.endTransmission();
if (r == 0) break;
delayMicroseconds(DELAY_USEC);
}

while (1) {
//Serial.print('%');
//Serial.flush();
Wire.beginTransmission((int)LIDARLite_ADDRESS); // transmit to LIDAR-Lite
Wire.write((int)RegisterHighLowB); // sets register pointer to (0x8f)
r = Wire.endTransmission();
if (r == 0) break;
delayMicroseconds(DELAY_USEC);
}

// request 2 bytes from LIDAR-Lite
while (1) {
//Serial.print('>');
//Serial.flush();
r = Wire.requestFrom((int)LIDARLite_ADDRESS, 2);
if (r > 0) break;
delayMicroseconds(DELAY_USEC);
}

if (Wire.available() >= 2) { // if two bytes were received
reading = Wire.read() * 256;
reading |= Wire.read();
tNew = millis();
dT = (tNew - tOld);
Serial.print(reading);
Serial.print(", ");
Serial.print(dT);
Serial.println();
tOld=tNew;
}

// lidar lite gives wrong results without this delay... why?
delayMicroseconds(100);
}
I ran it for maybe an hour and a half and it did not ever appear to hang or the like...
But again this is with the IC2 fixes that Paul did for this. These changes are in the latest builds. I am currently running the latest build 1.6.5r2 windows, with Teensyduino 1.24 beta 3... Hard to keep up with the Arduino releases!

It will be fun to see what your end version will be.

I wonder about maybe a Cylon like version, where it scans back and forth. Wonder about simply mounting on top of something like: MX-12w (I assume it can handle the weight). Wonder how far you can pan back and forth without stressing out the cables too much. I know it would not be as nice as being able to scan a full 360 degrees.

It also would be curious if these lidars would be sufficient for doing some of the ROS stuff like locomotion without the use of the primesense camera? If so how much CPU would these require? Would avoiding some of the things like OpenNI, OpenCV... might reduce CPU requirements for lower end setup? HR-OS1? Again sounds like lots of fun!

birdman
07-06-2015, 05:51 PM
I wonder about maybe a Cylon like version, where it scans back and forth. Wonder about simply mounting on top of something like: MX-12w (I assume it can handle the weight). Wonder how far you can pan back and forth without stressing out the cables too much. I know it would not be as nice as being able to scan a full 360 degrees.

Easiest way to do a repeating scan is to do a complete rotation like r3n33's original approach, but instead of a single mirror, use a pyramid of mirrors. (faceted mirrors on a continuous spin is how the repeating patterns of many laser scanners are done, as well as scanning imaging systems). It's far easier, more consistent, maintains constant angular speed (rather than the accelerate/cruise/decelerate of a back and forth scanner that can mess up the scan pattern and require more processing), and also eliminates any rocking back/forth torques applied to the base.

KurtEck
07-06-2015, 11:28 PM
Makes sense! Makes me think maybe I need 3d printer. And more importantly the skills to to design something to build on 3d printer ;)

birdman
07-07-2015, 08:31 AM
Makes sense! Makes me think maybe I need 3d printer. And more importantly the skills to to design something to build on 3d printer ;)

Get Sketchup (super easy to learn, and what I use for quickie 3D stuff for printing) and signup for 3Dhubs (a friend of mine started that company, it's basically crowdsourced 3D printing). Or find someone nearby who has one.

r3n33
07-07-2015, 04:52 PM
I agree with the Sketchup (http://www.sketchup.com/) recommendation. If you are wanting something easy to learn that will help you get your feet wet in both modeling and 3D printing it is a great way to start. Later down the road if you find you enjoy these sorts of things you can explore more powerful applications if needed. Over the last couple years I've found that in creating many of the basic 3D models for printing Sketchup has been the quickest tool for me. Perhaps if I spent a little more time in my other applications I'd pick them first but another advantage I like about Sketchup is the free license (when the pro trial expires). When working on files between work and personal machines I didn't have to worry about licensing issues.

I must admit it took me about a year to even try Sketchup because I thought it was going to be too basic. Shame on me for judging the book by it's cover :p

Slugman
07-07-2015, 09:31 PM
Sketchup's excellent when you make & use components, but once you have mock-ups of all the Bioloid parts it can take up too much of your time designing interesting new robots. Kinda like adult LEGO. I think I had those files (Sketchup version 6) loaded on here somewhere. I'll go back to lurking now. Carry on. :)
PS Nice work on the LIDAR btw.

Lurk........

Lurk...

r3n33
07-08-2015, 12:16 PM
Haha, thank you Slugman :)

r3n33
07-09-2015, 09:08 PM
Thank you PulsedLight for the quick turn around! I've got everything back up and running to a point I'm happy with so I'll make everything available to those who'd like to build on the idea.

The 3D models are on Thingiverse: http://www.thingiverse.com/thing:918950
The Arduino sketch and ROS driver are on github: https://github.com/r3n33/lidar-lite-ros-scanner-driver

I've ordered some hall sensors and reed switches to play with and I'd love to get my hands on a V2 sensor and revisit the original idea at some point so I'm not finished but I may slow down a bit while I work on other things. Time will tell :)

KurtEck
07-10-2015, 09:05 AM
Glad you got it back and have it up and running again!

As I mentioned earlier I now have a V2 on order (shipped today :D ). Also yesterday I ordered an MX-12w from Trossen (they have/had them back in stock), so I might still experiment some with scanning. Wondering how it would look on top of HR-OS1 ;)

KurtEck
07-14-2015, 06:52 PM
May still build one of these Mirror Scanner setups as is looks really great.

FYI - My V2 Lidar arrived and I have for now mounted it on top of an AX-12 servo, using one of my old Lynxmotion sensor brackets, with a spacer between bracket and sensor to make sure it does not run into any screws... I also had to drill some new holes in bracket as to fit the pattern on the sensor... Sort-of kludgy but:

6089
Next up to play with the code. May try to see if I can get it to output a compatible stream to what yours is doing.
Will probably limit my scan maybe to 180 degrees, maybe more...

Will be fun to see how fast it can really do the query. I just received an email from Pulsed light with a preliminary document/code to use the new I2C protocol. Don't have to deal with Acs and Naks, but instead read from Register 1 until a bit is 0 and then read the two bytes for the range...

Kurt

r3n33
07-15-2015, 11:47 AM
*whistles* I like the look of that blue sticker ;)

Can't wait to see what your findings are with the V2 sensor! Please make me order one now :p I'm really interested in what the maximum rate you can sample while maintaining the highest accuracy readings. 500Hz sure would be nice!!! With that much data we might want to switch to a binary stream to keep things speedy.

KurtEck
07-15-2015, 07:12 PM
Hopefully over the next few days, I will get some good stuff going. Today I was having problems with my Teensy code to run the Servos... Or maybe power issue... or maybe issues with Beta Teensyduino on latest Arduino. Time to get out Logic Analyzer...

KurtEck
07-18-2015, 10:01 AM
Yesterday my MX-12W servo arrived so I plan to replace the AX-12 with it...

What I am also wondering is what approach I want to take in the panning. I can think of several ways to do this including:
a) Tell servo to move N units (maybe 1), Do Measure, repeat... This was my first approach with AX servo and it at best was jerky...

b) Tell servo to do the pan using the Goal position and speed, maybe do query of servo to find it's current position and ask Lidar for data... (not sure if I would ask for position before or after the lidar query...

b1) Like above but maybe try to break up both parts/libraries where You issues the query to the servo and start the I2C for the pulse, then get back the data from both...

c) Like b) use seed control on servo, but instead of asking servo for it's position, you guesstimate it, knowing how long it is supposed to take. You might avoid doing samples at either end as to try to avoid issues with ramp speed...

Right now I am leaning toward c) I think I will end up with smoother pan and my guess is that not having to deal with as much UART traffic, things might be more likely to function...

Thoughts?

Kurt

P.S. - They have now put some beta example code up on github for the V2: https://github.com/PulsedLight3D/LIDARLite_v2_Arduino_Library/

jwatte
07-18-2015, 12:25 PM
I would use goal position and speed for the panning.
I'd probably sit in a tight loop, doing read-servo, read-lidar, read-servo, ...
Then use a weighted blend of the two servo position values for the estimated lidar position.

tician
07-18-2015, 12:34 PM
Or d) run the servo in continuous rotation mode to drive a cam+link to the Lidar mount with the Lidar's center on a pivot. Should be a 1:1 relationship between servo's 'present position' and Lidar's orientation with the same 'linger'/'high density' of scans near the edges/extremes of range/sweep and none of the multiple writes to the servo to change position or speed for every single sweep.

KurtEck
07-19-2015, 04:31 PM
Thanks guys,

Yesterday I started to play around with the MX servo and I think somehow I busted it :( I have it mounted in place of the AX-12 servo, with the only weight on it is a simple sensor bracket with Lidar lite mounted on it. So I can not imagine I overworked it... I have a simple program that told it to go to Min and then max at some speed (4 byte write to registers),
I then loop doing a 4 byte read (current pos, speed), when speed is zero I go the opposite direction. It hiccups some, which I was going to change and then it no longer talked... Thought maybe something funny with Teensy, so tried different one... still nothing... Then with just power connected to servo and not doing I noticed it was warm to touch... So unplugged... The servo still blinks once when I plug it in, so I think so level of processor is still working.

Today I tried talking to it with my simple AX test program, did not respond (AX-12 did). I then hooked up USB2AX to PC, and tried to run Dynamixel wizard to see if I could do a firmware recovery, it did not respond. I think I have used USB2AX for this before, but will search through my stuff for the USB2DYnamixel ...

So it looks like I am back to AX servo for now... Right now trying to figure out why it won't allow me to set the Servo return delay time... I tried doing it with my test program (tried to set to 0, 1, 10...), the data packet on AX buss looks OK, but the return packet gives error 0x8 (out of range)... The Dynamixel wizard over USB2AX did not appear to apply it either...

But probably should continue this on own thread.

jwatte
07-19-2015, 05:39 PM
Sounds like the servo TTL buffer chip might have broken? If the firmware recovery doesn't work, then that would be the most likely cause (assuming the plug isn't loose or something -- tried the connector on the other side?)

The PCB in the servo is generally covered by the 12 month warranty, so you may be able to get that replaced/fixed under warranty (at the cost of UPS ground shipping.)
But try the other connector and another cable, first :-)

KurtEck
07-20-2015, 09:39 AM
Thanks, will take the servo part offline as I am pretty sure servo is busted (neither port works for recovery), verified I could recover an AX servo so know setup works. Side note: after servo recovery on AX servo, it looks like the servo will now allow me to update the delay time...).

What I need to get back to is seeing how fast the Lidar-Lite V2 will respond with new protocol... And does the protocol hang like the V1 did... Probably still wire in the power on IO line to allow the code to reset it.

Kurt

KurtEck
07-20-2015, 06:51 PM
*whistles* I like the look of that blue sticker ;)

Can't wait to see what your findings are with the V2 sensor! Please make me order one now :p I'm really interested in what the maximum rate you can sample while maintaining the highest accuracy readings. 500Hz sure would be nice!!! With that much data we might want to switch to a binary stream to keep things speedy.
Sorry, I know that I have been playing around with some other stuff (like trying to get an MX servo to pan). So today I decided to make a version of your program (but for Teensy), with V2, using their now new Arduino library. (https://github.com/PulsedLight3D/LIDARLite_v2_Arduino_Library/) Note: their library includes a few different sample programs.

I don't have it spinning with your motor and the like but did setup Interval timer that incremented and toggled IO pins like you had, plus I had it output the stuff you did. It ran pretty good for maybe 20 minutes and finally naked and hung. Will reboot it now and see how it goes. It started up again...

Here is a some of the output:

7.20,219,4294967295.///,1
7.88,217,4294967295.///,3
8.11,216,4294967295.///,2
8.56,218,4294967295.///,1
8.78,218,4294967295.///,2
9.23,217,4294967295.///,2
9.68,217,4294967295.///,2
9.91,217,4294967295.///,1
10.36,216,4294967295.///,2
10.81,218,4294967295.///,3
11.26,218,4294967295.///,1
11.71,217,4294967295.///,3
11.93,217,4294967295.///,2
12.38,216,4294967295.///,1
12.83,216,4294967295.///,2
13.06,216,4294967295.///,2
13.51,217,4294967295.///,2
13.73,217,4294967295.///,1
14.18,217,4294967295.///,2
14.63,218,4294967295.///,2
15.31,219,4294967295.///,3
15.53,219,4294967295.///,2
16.21,219,4294967295.///,2
16.44,218,4294967295.///,2
16.89,218,4294967295.///,2
17.34,218,4294967295.///,2
17.79,218,4294967295.///,2
18.24,216,4294967295.///,2

So if I am readding this correct the last value is the millis, which looks pretty good. This can also go faster as there is an option to turn off pre-amp stabilization and reference pulse which is supposed to speed it up some.

In case you are curious about the code:

//================================================== ==============================
// r3n33 Lidar Lite Ros scanner Arduino program
// Hacked up by Kurt Eckhardt to work on a Teensy 3.1 with a V2 of the Lidar Lite.
//================================================== ==============================

//================================================== ==============================
// Include files
//================================================== ==============================
#include <Wire.h>
#include <LIDARLite.h>

//================================================== ==============================
// Defines
//================================================== ==============================

#define LIDARLite_ADDRESS 0x62 // Default I2C Address of LIDAR-Lite.
#define RegisterMeasure 0x00 // Register to write to initiate ranging.
#define MeasureValue 0x04 // Value to initiate ranging.
#define RegisterHighLowB 0x8f // Register to get both High and Low bytes in 1 call.

#define DELAY_USEC 50

#define STEP_SPEED 1100

//================================================== ==============================
// Global Variables.
//================================================== ==============================
int reading = 0;
long dT;
long tNew, tOld; // time in milliseconds()

int pin_led = 13;
int pin_step = 11;
int pin_dir = 10;
int pin_lidar_power = 8;

// Create a new LIDARLite instance
LIDARLite myLidarLite;

IntervalTimer myTimer;
volatile int motorStepCnt = 0;
int stepsPerRevolution = 1599;
float motorPos;
float secondsPerDegree = 0;
int lastMotorPos = -1;
int lastSpeed = 0;




//================================================== ==============================
// setup - Main Arduino setup function.
//================================================== ==============================
void setup( void )
{
Wire.begin();
Serial.begin(115200);
while (!Serial) ;
delay(10);
Serial.println("LIDAR Test");
tOld = millis();

pinMode(pin_led, OUTPUT);
pinMode(pin_step, OUTPUT);
pinMode(pin_dir, OUTPUT);
pinMode(pin_lidar_power, OUTPUT);

digitalWrite(pin_lidar_power, HIGH); //Turn lidar on

digitalWrite(pin_dir,LOW); //Motor Step Direction
Serial.println("Before lidar begin");
Serial.flush();
myLidarLite.begin(1,true, false);
Serial.println("After Lidar begin");
Serial.flush();
myTimer.begin(stepmotor, STEP_SPEED);

// Take first reading with pream stabilization and reference pulse
Serial.println(myLidarLite.distance());
}

//================================================== ==============================
// main Loop function.
//================================================== ==============================
void loop( void )
{
digitalWrite(pin_led, !digitalRead(pin_led));
reading = myLidarLite.distance(/*false, false*/); // Trun off preamp stab and reference pulse?
tNew = millis();
dT = (tNew - tOld);
if ( reading < 1024 && reading > 0 )
{
motorPos = (360.0 / stepsPerRevolution) * motorStepCnt;

calculate_speed( motorPos, dT );

Serial.print( motorPos );
Serial.print(",");
Serial.print(reading);
Serial.print(",");
Serial.print(secondsPerDegree,3);
Serial.print(",");
Serial.print(dT);
Serial.println();
}
tOld=tNew;

if ( dT > 100 )
{
cycle_lidar_power();
}
}

//================================================== ==============================
// stepmotor - Timer function to step the motor...
//================================================== ==============================
void stepmotor( void )
{
digitalWrite(pin_step, HIGH);
if ( ++motorStepCnt > stepsPerRevolution )
{
motorStepCnt = 0;
}
digitalWrite(pin_step, LOW);
}

//================================================== ==============================
// Calculate Speed
//================================================== ==============================
void calculate_speed( int p_position, int p_interval )
{
int degreesTraveled;
if ( p_position > lastMotorPos )
{
degreesTraveled = p_position - lastMotorPos;
}
else
{
degreesTraveled = p_position - lastMotorPos + 360;
}
lastMotorPos = p_position;
float secsPerDeg = ( p_interval / 1000.0/*milliseconds*/ ) / degreesTraveled;
secondsPerDegree = ( 0.9 * secondsPerDegree ) + ( 0.1 * secsPerDeg );
}


//================================================== =========================================
// cycle_lidar_power - Try to recover after lidar hangup...
//================================================== =========================================
void cycle_lidar_power(void)
{
digitalWrite(pin_lidar_power, LOW);
delay(1);
digitalWrite(pin_lidar_power, HIGH);
delay(1);
}

r3n33
07-20-2015, 07:20 PM
Awesome results! 1,2,3ms per reading is SO nice in comparison. Now I really want one to play with :D

Thank you!

Two things I noticed from your output Kurt.. You changed motorPos to a float (which is fine) but when you get to the ROS code an int is expected so heads up. I probably should have stored a float like you did and explicitly cast an int in the output.

Also it seems my calculation for seconds per degree isn't working as expected in your output. What I'd expect to see is more like this...



251,289,0.005,15
253,289,0.005,12
256,290,0.005,15
259,290,0.005,15
262,290,0.005,15
265,290,0.005,14
268,290,0.005,16
271,289,0.005,14
274,290,0.005,15
277,290,0.005,15
280,291,0.005,14
283,290,0.005,16
286,290,0.005,12
289,290,0.005,15

KurtEck
07-20-2015, 07:37 PM
Actually I did not mean to switch stuff :o like motorpos. I am thinking that maybe it got switched when I merged code from a few different places. I think it came from your earlier program in posting #47... Will check and switch to match yours. Although with faster samplings can now get multiple samples per degree... Wonder if we should go more ROS and use radians?

Yep I was wondering about that value being output, may have to debug some.

Probably need to look at your ROS stuff to see how the 4 values are used.

Kurt

KurtEck
07-20-2015, 08:20 PM
Quick update: I need to play some wit the calculate speed function:

void calculate_speed( int p_position, int p_interval )
{
int degreesTraveled;
if ( p_position > lastMotorPos )
{
degreesTraveled = p_position - lastMotorPos;
}
else
{
degreesTraveled = p_position - lastMotorPos + 360;
}
lastMotorPos = p_position;
secsPerDeg = ( p_interval / 1000.0/*milliseconds*/ ) / degreesTraveled;
secondsPerDegree = ( 0.9 * secondsPerDegree ) + ( 0.1 * secsPerDeg );
}

I updated the function to also output secsPerDeg to help debug... This except should give a few clues:
Darn new Arduino when I unplug USB cable it still shows the data, but it is grayed out which is fine, but you can not copy to clipboard... So will describe:
Suppose you call twice with p_position = 0 degrees.

In the code the line if ( p_position > lastMotorPos ) will be false as they are equal, so it will calculate that:
we went: 360 degrees (0-0+360)

Where the calculation went off was Call with 360 degrees followed by 0 degrees.
It will calculate: degreesTraveled = (0 - 360) + 360 or 0 degrees.
At which point secsPerDegree we will get a divide by zero.

My guess is that 360 should have been 0...

jwatte
07-21-2015, 11:02 AM
You could assume that the servo never travels more than 180 degrees (either direction) per poll.

Or you could change the ">" to a ">=" if you will ever only travel in one direction.
Though, if the encoder is slightly noisy, you may get a second reading that's one tick less than the previous reading, so checking if (p_position > lastMotorPos - 4) or something would probably be even safer!

KurtEck
07-21-2015, 12:15 PM
Thanks jwatte,

Yep I fixed yesterday with >=. Actually in two places. The place where the motor number is incremented as to avoid the 360 degrees issue. Plus in the function I mentioned as to give me the right answer if two equal measurements. Then handled case where delta was zero as to not divide by zero... Could post current stuff if anyone is interested. Or I think I will do a little more stuff and probably convert the angles to eigher floating point, or 10ths of degree or radians to make consistent with ROS.

Also I think the sensor timings may be influenced by how much stuff I am outputting, so was thinking of maybe converting formats... Maybe binary, maybe multiple sensor outputs per message...

Squid737
03-15-2016, 03:07 PM
Hey everyone. I was just surfing the web and came across this thread. I have been working on something very similar independently, and found it interesting to read all of your comments because they essentially mimicked my thought and development process while developing my own 360 mirror based lidar system with the PulsedLight LiDAR. Your problem with one emitter hitting on the high side of the mirror and the other hitting on the low side, the implementation of a gear system, and you guys even discussed using a slip ring to allow continuous rotation. I only wish that I had found this thread earlier (which I came across in a deep, deep Google search), because my time frame was about the same as yours, with most of my work and development taking place in summer 2015 around the same time. I could have saved a lot of time and offered a lot of input! I know this is an old thread, but I thought it might be interesting to you guys if I shared what I came up with independently. My original 3D printed base was quite similar to your set up, but after success with that I printed a new one to add three-dimension functionality.

50.129.48.17/contact/images/LIDAR.mp4
50.129.48.17/contact/images/output.gif


PS the most easy and effective method for improving data point accuracy was using a first-surface mirror, a mirror with the reflective surface on the front of the glass. I ordered one from a kaleidoscope company who specialize in high quality optical mirrors. Less than $10. The way the PulsedLight LiDAR works is by splitting a laser beam into two beams with resulting wavelength A and wavelength B initially in phase. Then it emits each wavelength from a different lens, which are positioned at offset heights (You can observe this by looking at the physical LiDAR device and noticing how one lens is further recessed than the other). This gives the wavelength B from the recessed lens a further fixed distance to travel, meaning that when it is received back to the device, wavelength B will be offset by wavelength A by some amount. The device then compares received original wavelength A with received recessed wavelength B, and given the known lens offset distance and the offset of the wavelength phases, it is able to determine a distance. It works very similar to the famous Michealson-Morely experiment Other than the fact that that it is interesting, I share this because with a back-surface mirror, especially the thick mirror that you are using, there are cases of "ghosting" (See image). When the LIDAR device detects wavelength A and a "ghosted" wavelength B, it increases the measured offset and perceives and increased phase offset, which gives a much less accurate distance.
https://s-media-cache-ak0.pinimg.com/236x/41/12/ef/4112efd6bf7b987f9c8d0d02baabac44.jpg

Michealson-Morely Experiment explained for those curious

https://www.youtube.com/watch?v=3G_Q6AggQF8

r3n33
03-17-2016, 03:21 PM
Hello!

Your project looks great! And the results are fantastic.

It looks like you were using the LIDAR-Lite V1.. have you tried the V2? What was the acquisition time in the sample gif you provided?

Squid737
03-20-2016, 12:08 PM
Thank you!

Oh yes, I should have provided some info for that scan. It took about 5 minutes to complete that scan, but that was using one of the slower scan algorithms I have been using for testing. The horizontal (theta) step size was 1/2 and the vertical (phi) step size was 1/2 as well. That scan was taken with the LIDAR v1, which has an acquisition time of about 66-70 pts per second. However, my rig is set up to run two v2s, which will increase my scan efficiency by roughly 2000%. Theoretically, this means that I could take a full 360 scan at 1/2 x 1/2 step resolution (roughly 127500 pts) in a little more than 2 minutes. I would love to use the new v2s, but robotshop has them on backorder, and I cant find them anywhere else. I'm excited for them to get new stock, because then I can realistically set the step size to 1/16 x 1/16 and take scans of 10 million points in 2 hours! It will be interesting.

Squid737
03-20-2016, 12:46 PM
I will go ahead and post this here, as well. If anyone here has a LIDAR-Lite v2 that they would allow me to purchase, I am pretty much desperate and would pay full market price for a used unit. I'm doing a presentation which looks at the efficiency of different scanning algorithms at Butler University's URC on April 8th, and they discontinued the v2, which I designed my entire project around. You can find more details in the post I made in the "Garage Sale" section. If you have a LIDAR-Lite v2, please e-mail me at [email protected] and we can try to work something out. Even if you don't want to part ways with it for good, I would be happy to 'rent' it from you. I'll even pay for shipping and offer a cash deposit until it is returned to you. I would be happy to mention you in my presentation and research paper, both of which will be published.


http://forums.trossenrobotics.com/showthread.php?7833-Owners-of-a-PulsedLight-LIDAR-Lite-v2-Laser-Rangefinder-click-here-Will-purchase-at-high-price