[PYTHON] Visualize event congestion in public space with a laser rangefinder
Overview
- An experiment was attempted to count and visualize the congestion status of Marche in public space over a two-day period.
- It is necessary to narrow down the entrance and exit to measure the traffic volume, the number of people staying, and the length of stay. This time, the amount of people passing by at a certain point in the venue is regarded as the degree of congestion.
- The number of visitors at the event is valuable data. Try to see how much you can count unattended
- We would like to thank the Ekikita Town Development Conference (https://ekikita.jp), which manages the area of the north exit of Hiroshima Station.
【reference】
About area management (Ministry of Land, Infrastructure, Transport and Tourism)
https://www.mlit.go.jp/common/001059393.pdf
Regional Revitalization Town Development --Area Management- (Cabinet Secretariat Town / People / Work Creation Headquarters Secretariat)
https://www.kantei.go.jp/jp/singi/sousei/about/areamanagement/areamanagement_panf.pdf
What to prepare
- Raspberry Pi3 Model B (4 is probably okay)
- Case for Raspberry Pi
- Heat sink and fan for Raspberry Pi
- Raspberry Pi3 Model B B + compatible power supply set (5V 3.0A)
- vl53l1x Ultrasonic distance sensor (maximum measurement range 4m)
- LED, 330Ω resistor
- 100-yen shop tripod
- AirPods case purchased at a 100-yen shop (used as a sensor cover)
Preparation
- Set up the Raspberry Pi so that you can connect to Wifi.
https://www.raspberrypi.org/downloads/
- Make the Ambient (IoT visualization service) library available.
- Create a dashboard in Ambient and get the channel ID and light key.
https://ambidata.io/refs/python/
- Make vl53l1x library for Python available
https://github.com/pimoroni/vl53l1x-python
assembly
- Connect Raspberry Pi, laser distance sensor and LED as follows
programming
- Programming with Python3 to use a generic library
- Modify and use distance.py in the examples folder of the git cloned library
- The value of the laser distance sensor is looped and read, and the number below the threshold is counted as the number of passes.
- Turn on / off the LED connected to the GPIO pin each time you count
- Send counts every 5 minutes to Ambient for visualization
distance.py
#!/usr/bin/env python
import time
import sys
import signal
import VL53L1X
import ambient
import datetime
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setup(25, GPIO.OUT) #For LED blinking
from time import sleep
print("""distance.py
Display the distance read from the sensor.
Uses the "Short Range" timing budget by default.
Press Ctrl+C to exit.
""")
ambi = ambient.Ambient(xxxxx, 'xxxxxxxxxxxxxxxx') #← ambient channel ID and light key
count = 0
sndcnt = 0
# Open and start the VL53L1X sensor.
# If you've previously used change-address.py then you
# should use the new i2c address here.
# If you're using a software i2c bus (ie: HyperPixel4) then
# you should `ls /dev/i2c-*` and use the relevant bus number.
tof = VL53L1X.VL53L1X(i2c_bus=1, i2c_address=0x29)
tof.open()
# Optionally set an explicit timing budget
# These values are measurement time in microseconds,
# and inter-measurement time in milliseconds.
# If you uncomment the line below to set a budget you
# should use `tof.start_ranging(0)`
tof.set_timing(66000, 70)
tof.start_ranging(0) # Start ranging
# 0 = Unchanged
# 1 = Short Range
# 2 = Medium Range
# 3 = Long Range
running = True
def exit_handler(signal, frame):
global running
running = False
tof.stop_ranging()
print()
sys.exit(0)
# Attach a signal handler to catch SIGINT (Ctrl+C) and exit gracefully
signal.signal(signal.SIGINT, exit_handler)
while running:
distance_in_mm = tof.get_distance()
print("Distance: {}mm".format(distance_in_mm))
now = datetime.datetime.now()
minute = '{0:%M}'.format(now)
second = '{0:%S}'.format(now)
print(minute)
print(second)
if distance_in_mm < 1300: #Threshold for counting or not(mm)
count += 1
GPIO.output(25, GPIO.HIGH) #LED blinking
sleep(0.5)
GPIO.output(25, GPIO.LOW)
sleep(0.5)
if int(minute) % 5 == 0 and int(second) == 0:
if sndcnt < 1:
r = ambi.send({'d1': count})
if r.status_code != 200:
continue
print(count)
print("***sended***\n")
count = 0
sndcnt += 1
else:
sndcnt = 0
time.sleep(0.1)
State of installation on site
result
- It was not possible to count normally throughout the time of the event.
- Adjustment Although adjustments were made locally, such as changing the installation location and threshold value, stable counting was not possible.
Red background: The part where the data was acquired
Blue background: Adjusting
Gray background: After the event
Bug content
- The value of the laser rangefinder is not stable. Stability changes depending on the material (stone, wood, paper) of the object and the unevenness of the surface.
- Passing by one person will be counted as two or three people. (It improved to some extent by putting a wait when it was detected)
- It seems that there is a big difference in brightness and stability between when it is not exposed to sunlight and when it is not exposed to sunlight.
- Once every few hours, I get an HTTP MaxRetryError for the ambient api URL.
Since my home Wifi has been operating for more than 10 hours, it is highly possible that it is due to the Wifi equipment rented locally.
For the future
- It is difficult to hold an indoor event due to the corona vortex, but first we will continue to make adjustments so that we can count reliably indoors.
- For problems that are difficult to count outdoors, consider considering other types of sensors
- When using a ToF type rangefinder, prepare an object that can reflect stably.
- It is necessary to test in advance whether there is a problem with long-term connection in the local Wifi environment