Skip to content

VoxoTech/PiDAR

Repository files navigation

PiDAR - DIY 360° 3D Panorama Scanner

WORK IN PROGRESS!

Core Features:

  • LiDAR: custom serial driver for LDRobot LD06, LD19 or STL27L

    • CRC package integrity check
    • calibrated PWM control using curve fitting
    • 2D live visualization and export (numpy or CSV)
  • Panorama: 6K 360° spherical map

    • stitched from fisheye photos using Hugin Panorama photo stitcher
    • constant camera exposure by reading EXIF data of automatic
    • constant white balance by iterative optimization of color gains
  • 3D Scene: assembly of 3D scenes from 2D planes based on angle and offsets

    • sampling vertex colors from panorama
    • Open3D visualization and export (PCD, PLY or e57)
    • aligning multiple scenes using global registration and ICP fine-tuning
    • Poisson Surface Meshing (very slow on Pi4, recommended to run on PC)

Hardware Specs:

  • LDRobot LD06, LD19 or STL27L LiDAR

  • Raspberry Pi HQ Camera with ArduCam M12 Lens (M25156H18, p.7)

  • Raspberry Pi 4

  • NEMA17 42-23 stepper with A4988 driver

  • Power Supply:

    • v1: 2x 18650 Batteries (7.2V) with step-down converter
    • v2: 10.000 mAh USB Powerbank with step-up converter
  • 3D printed:

PiDAR 360° Laserscanner

Version 1 (using 2x 18650 Batteries):

wiring

breadboard version 2.0.1

Version 2 - (37Wh Powerbank with Step-Up converter + Relay for power efficiency)

LD06 / STL27L:

  • UART Tx (yellow)
  • PWM (white)
  • GND (black)
  • VCC 5V (red)

Raspberry Pi:

  • LD06 UART0 Rx: GP15
  • LD06 PWM0: GP18
  • Power Button: GP03
  • Scan Button: GP17
  • A4988 direction: GP26, step: GP19
  • A4988 microstepping mode: GP5, GP6, GP13

Power Button

Power LED and CPU fan

sudo nano /boot/firmware/config.txt

# CPU fan at lower temp
dtoverlay=gpio-fan,gpiopin=4,temp=45000

# Power LED Heartbeat:
dtparam=pwr_led_trigger=timer

Scan Button: register GPIO interrupt

create new service for autostart

sudo nano /etc/systemd/system/pidar.service

content:

[Unit]
Description=GPIO interrupt for PiDAR Scan Button
After=network.target

[Service]
Type=simple
ExecStart=/usr/bin/python3 /home/pi/Documents/PiDAR/gpio_interrupt.py
Restart=always
RestartSec=2

[Install]
WantedBy=multi-user.target

reload daemon, enable and start service:

sudo systemctl daemon-reload
sudo systemctl enable pidar.service
sudo systemctl start pidar.service

check service if necessary:

sudo systemctl status pidar.service

Serial Protocol

LD06

baudrate 230400, data bits 8, no parity, 1 stopbit
sampling frequency 4500 Hz, scan frequency 5-13 Hz, distance 2cm - 12 meter, ambient light 30 kLux

total package size: 48 Byte, big endian.

  • starting character:Length 1 Byte, fixed value 0x54, means the beginning of data packet;
  • Data Length: Length 1 Byte, the first three digits reserved, the last five digits represent the number of measured points in a packet, currently fixed value 12;
  • speed:Length 2 Byte, in degrees per second;
  • Start angle: Length: 2 Byte; unit: 0.01 degree;
  • Data: Length 36 Byte; containing 12 data points with 3 Byte each: 2 Byte distance (unit: 1 mm), 1 Byte luminance. For white objects within 6m, the typical luminance is around 200.
  • End Angle: Length: 2 Byte; unit: 0.01 degree;
  • Timestamp: Length 2 Bytes in ms, recount if reaching to MAX 30000;
  • CRC check: Length 1 Byte

The Angle value of each data point is obtained by linear interpolation of the starting angle and the ending angle.
The calculation method of the angle is as following:

step = (end_angle – start_angle)/(len – 1)  
angle = start_angle + step*i  

len is the length of the packet, and the i value range is [0, len].

set Permission for UART on Raspberry Pi

temporary solution:

sudo chmod a+rw /dev/ttyS0

old solution: make it permanent by disabling password for chmod:

sudo visudo
pi ALL=(ALL:ALL) NOPASSWD: /usr/bin/chmod a+rw /dev/ttyS0

then execute the temporary solution from python:

import subprocess
command = "sudo chmod a+rw /dev/ttyS0"
process = subprocess.Popen(command.split(), stdout=subprocess.PIPE)
output, error = process.communicate()

new solution: grant permissions to the serial port using udev rules

(TODO: check and remove old!)

  • forget about visudo and the subprocess call above.
  • Open a terminal and run the following command: sudo nano /etc/udev/rules.d/50-ttyS0.rules
  • Write the following line in the file and save it: KERNEL=="ttyS0",GROUP="dialout",MODE="0660"
  • Run the following command to check if your user is a member of the dialout group: groups
  • If you see dialout in the output, you are already a member of the group. If not, run the following command to add your user to the group: sudo usermod -a -G dialout pi
  • Run the following command to reload the udev rules: sudo udevadm control --reload-rules
  • Unplug and replug the serial device, or reboot the system, to apply the changes.

Hardware PWM on Raspberry Pi

enable GPIO_18 (PWM0) and GPIO_19 (PWM1)

echo "dtoverlay=pwm-2chan" >> /boot/config.txt 

check if "pwm_bcm2835" now exists:

lsmod | grep pwm

Install RPi Hardware PWM library:

pip install rpi-hardware-pwm

Panorama Stitching

install Hugin with enblend plugin

sudo apt-get install hugin-tools enblend

LDRobot LiDAR Specs

LD06 vs. STL27L

LD06:

STL27L:

Troubleshooting

poor performance of VS Code on Raspberry Pi

disable hardware acceleration for VS Code (source)

Preferences: Configure Runtime Arguments  
Set "disable-hardware-acceleration": true

pye57 on Raspberry Pi

there is no wheel for arm64. build requires libxerces:

sudo apt install libxerces-c-dev
pip install pye57

links and references:

inspirations

another Lidar implementation in Python

ICP implementations:

3D Demo Data for global registration, ICP, meshing etc.:

About

sophisticated 360° 3D Panorama Scanner: LDRobot LD06 LiDAR @ Raspberry Pi Pico | HQ Camera + M12 Fisheye Lens + Hugin @ Raspberry Pi 4 | Nema17 @ A4988

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages