Skip to content

Refactor the sensor library #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.vscode/
__pycache__
build/
dist/
**.egg-info/
19 changes: 19 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
MIT License

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
34 changes: 16 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,28 +1,26 @@
# TF-Luna LiDAR with Raspberry Pi
Python codes for configuring and reading the TF-Luna Light Detection And Ranging (LiDAR) module interfaced with a Raspberry Pi computer.
# TF-Luna LiDAR Python Driver

Tutorial: https://makersportal.com/blog/distance-detection-with-the-tf-luna-lidar-and-raspberry-pi
The [TF-Luna sensor](https://www.dfrobot.com/product-1995.html) is a LiDAR sensor, which can be read either with I2C or Serial.

Buy a TF-Luna from our Store: https://makersportal.com/shop/tf-luna-lidar-module
This repository contains the code permitting to use the TF-Luna sensor with the serial interface.

#
This repository is a fork of [tfluna-python](https://github.com/makerportal/tfluna-python), and is a rewrite of the driver to a class-based structure.
The new code is also more careful when it comes to handling the serial interface: this driver is indeed intended to be used (only) as a Python resource, i.e. as follows (more details in the `example` folder):

```
import tfluna
import timeout_decorator

with tfluna.TfLuna(baud_speed=115200, serial_name="/dev/serial0") as tfluna:
tfluna.get_version()
tfluna.set_samp_rate(10)
#tfluna.set_baudrate(57600) # can be used to change the baud_speed
distance,strength,temperature = tfluna.read_tfluna_data()
```

### - TF-Luna + Raspberry Pi Wiring -

The TF-Luna can be wired to the Raspberry Pi via the mini UART port:

![TF-Luna RPi Wiring](https://static1.squarespace.com/static/59b037304c0dbfb092fbe894/t/6009f277b8566661c36dfa67/1611264637375/TF_luna_RPi_wiring.png?format=1500w)

---
### - TF-Luna Ranging Test -

The script entitled 'tfluna_test_plot.py' outputs a plot similar to the following:

![TF-Luna Ranging Test](./images/tfluna_test_plot_white.png)

---
### - Real-Time Ranging Visualization -

The script entitled 'tfluna_test_realtime.py' outputs a real-time output of distance and signal strength, similar to the following:

![TF-Luna Real-Time Ranging](./images/tfluna_realtime_plot_white.png)
93 changes: 93 additions & 0 deletions examples/tfluna_realtime.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
######################################################
# Copyright (c) 2021 Maker Portal LLC
# Author: Joshua Hrisko
# Code refactoring (to classes): Clément Nussbaumer, April 2021
######################################################
#
# TF-Luna Mini LiDAR wired to a Raspberry Pi via UART
# --- Real-time ranging with signal strength indicator
#
#
######################################################
#

import tfluna

import time
import numpy as np
import matplotlib.pyplot as plt

#
##############################################
# Plotting functions
##############################################
#
def plotter():
################################################
# ---- start real-time ranging and strength bar
################################################
#
plt.style.use('ggplot') # plot formatting
fig,axs = plt.subplots(1,2,figsize=(12,8),
gridspec_kw={'width_ratios': [5,1]}) # create figure
fig.canvas.set_window_title('TF-Luna Real-Time Ranging')
fig.subplots_adjust(wspace=0.05)
# ranging axis formatting
axs[0].set_xlabel('Sample',fontsize=16)
axs[0].set_ylabel('Amplitude',fontsize=16) # amplitude label
axs[0].set_xlim([0.0,plot_pts])
axs[0].set_ylim([0.0,8.0]) # set ranging limits
# signal strength axis formatting
axs[1].set_xlim([-1.0,1.0]) # strength bar width
axs[1].set_xticks([]) # remove x-ticks
axs[1].set_ylim([1.0,2**16]) # set signal strength limits
axs[1].yaxis.tick_right() # move strength ticks to right
axs[1].yaxis.set_label_position('right') # label to right
axs[1].set_ylabel('Signal Strength',fontsize=16,labelpad=6.0)
axs[1].set_yscale('log') # log scale for better visual
# draw and background specification
fig.canvas.draw() # draw initial plot
ax1_bgnd = fig.canvas.copy_from_bbox(axs[0].bbox) # get background
ax2_bgnd = fig.canvas.copy_from_bbox(axs[1].bbox) # get background
line1, = axs[0].plot(np.zeros((plot_pts,)),linewidth=3.0,
color=plt.cm.Set1(1)) # dummy initial ranging data (zeros)
bar1, = axs[1].bar(0.0,1.0,width=1.0,color=plt.cm.Set1(2))
fig.show() # show plot
return fig,axs,ax1_bgnd,ax2_bgnd,line1,bar1

def plot_updater():
##########################################
# ---- time series
fig.canvas.restore_region(ax1_bgnd) # restore background 1 (for speed)
fig.canvas.restore_region(ax2_bgnd) # restore background 2
line1.set_ydata(dist_array) # update channel data
bar1.set_height(strength) # update signal strength
if strength<100.0 or strength>30000.0:
bar1.set_color(plt.cm.Set1(0)) # if invalid strength, make bar red
else:
bar1.set_color(plt.cm.Set1(2)) # green bar
axs[0].draw_artist(line1) # draw line
axs[1].draw_artist(bar1) # draw signal strength bar
fig.canvas.blit(axs[0].bbox) # blitting (for speed)
fig.canvas.blit(axs[1].bbox) # blitting
fig.canvas.flush_events() # required for blitting
return line1,bar1
#
############################
# Real-Time Plotter Loop
############################
#
with tfluna.TfLuna(baud_speed=115200) as tfluna:
tfluna.get_version()

plot_pts = 100 # points for sample rate test
fig,axs,ax1_bgnd,ax2_bgnd,line1,bar1 = plotter() # instantiate figure and plot
dist_array = [] # for updating values
print('Starting Ranging...')
while True:
distance,strength,temperature = tfluna.read_tfluna_data() # read values
dist_array.append(distance) # append to array
if len(dist_array)>plot_pts:
dist_array = dist_array[1:] # drop first point (maintain array size)
line1,bar1 = plot_updater() # update plot

33 changes: 33 additions & 0 deletions examples/tfluna_simple_read.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
######################################################
# Copyright (c) 2021 Maker Portal LLC
# Author: Joshua Hrisko
# Author of the refactoring (to classes): Clément Nussbaumer, April 2021
######################################################
#
# TF-Luna Mini LiDAR wired to a Raspberry Pi via UART
# --- testing the distance measurement from the TF-Luna
#
######################################################
#
import time
import numpy as np

import tfluna
import timeout_decorator

with tfluna.TfLuna(baud_speed=115200) as tfluna:
try:
tfluna.get_version()
tfluna.set_samp_rate(10)
#tfluna.set_baudrate(57600)
#tfluna.set_baudrate(115200)

for i in range(10):
distance,strength,temperature = tfluna.read_tfluna_data() # read values
print(
f"Distance: {distance:2.2f} m, "
f"Strength: {strength:2.0f} / 65535 (16-bit), "
f"Chip Temperature: {temperature:2.1f} C") # print sample data

except timeout_decorator.TimeoutError:
print(f"Timeout while communicating with the Tf Luna sensor, exiting")
48 changes: 48 additions & 0 deletions examples/tfluna_test_plot.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
######################################################
# Copyright (c) 2021 Maker Portal LLC
# Author: Joshua Hrisko
# Code refactoring (to classes): Clément Nussbaumer, April 2021
######################################################
#
# TF-Luna Mini LiDAR wired to a Raspberry Pi via UART
# --- test ranging plotter for TF-Luna
#
#
######################################################
#
import time
import numpy as np

import tfluna
#
############################
# Testing the TF-Luna Output
############################
#
with tfluna.TfLuna(baud_speed=115200) as tfluna:

tot_pts = 100 # points for sample rate test
time_array,dist_array = [],[] # for storing values
print('Starting Ranging...')
while len(dist_array)<tot_pts:
try:
distance,strength,temperature = tfluna.read_tfluna_data() # read values
dist_array.append(distance) # append to array
time_array.append(time.time())
except:
continue
print('Sample Rate: {0:2.0f} Hz'.format(len(dist_array)/(time_array[-1]-time_array[0]))) # print sample rate
#
##############################
# Plotting the TF-Luna Output
##############################
#
import matplotlib.pyplot as plt

plt.style.use('ggplot') # figure formatting
fig,ax = plt.subplots(figsize=(12,9)) # figure and axis
ax.plot(np.subtract(time_array,time_array[0]),dist_array,linewidth=3.5) # plot ranging data
ax.set_ylabel('Distance [m]',fontsize=16)
ax.set_xlabel('Time [s]',fontsize=16)
ax.set_title('TF-Luna Ranging Test',fontsize=18)
plt.show() # show figure
Binary file removed images/tfluna_realtime_plot_white.png
Binary file not shown.
Binary file removed images/tfluna_test_plot_white.png
Binary file not shown.
6 changes: 6 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[build-system]
requires = [
"setuptools>=42",
"wheel"
]
build-backend = "setuptools.build_meta"
2 changes: 2 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pyserial
timeout-decorator
24 changes: 24 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
[metadata]
name = tfluna-driver
version = 0.1.0
author = Clément Nussbaumer
author_email = [email protected]
description = Code to read measurements from a Tf-Luna LiDAR sensor.
long_description = file: README.md
long_description_content_type = text/markdown
url = https://github.com/clementnuss/tfluna-python
project_urls =
Bug Tracker = https://github.com/clementnuss/tfluna-python
classifiers =
Programming Language :: Python :: 3
License :: OSI Approved :: MIT License
Operating System :: OS Independent

[options]
package_dir =
= src
packages = find:
python_requires = >=3.6

[options.packages.find]
where = src
1 change: 1 addition & 0 deletions src/tfluna/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from .tfluna import TfLuna
Loading