467 lines
13 KiB
Markdown
467 lines
13 KiB
Markdown
+++
|
|
title = "Übersetzung: AIRASPI Build Log"
|
|
authors = ["Aron Petau"]
|
|
description = "Utilizing an edge TPU to build an edge device for image recognition and object detection"
|
|
date = 2024-01-30
|
|
[taxonomies]
|
|
tags = [
|
|
"coral",
|
|
"docker",
|
|
"edge TPU",
|
|
"edge computing",
|
|
"frigate",
|
|
"local AI",
|
|
"private",
|
|
"raspberry pi",
|
|
"surveillance"
|
|
]
|
|
[extra]
|
|
show_copyright = true
|
|
show_shares = true
|
|
+++
|
|
|
|
## AI-Raspi Build Log
|
|
|
|
This should document the rough steps to recreate airaspi as I go along.
|
|
|
|
Rough Idea: Build an edge device with image recognition and object detection capabilites.\
|
|
It should be realtime, aiming for 30fps at 720p.\
|
|
Portability and usage at installations is a priority, so it has to function without active internet connection and be as small as possible.\
|
|
It would be a real Edge Device, with no computation happening in the cloud.
|
|
|
|
Inspo from: [pose2art](https://github.com/MauiJerry/Pose2Art)
|
|
|
|
|
|
## Hardware
|
|
|
|
- [Raspberry Pi 5](https://www.raspberrypi.com/products/raspberry-pi-5/)
|
|
- [Raspberry Pi Camera Module v1.3](https://www.raspberrypi.com/documentation/accessories/camera.html)
|
|
- [Raspberry Pi GlobalShutter Camera](https://www.raspberrypi.com/documentation/accessories/camera.html)
|
|
- 2x CSI FPC Cable (needs one compact side to fit pi 5)
|
|
- [Pineberry AI Hat (m.2 E key)](https://pineberrypi.com/products/hat-ai-for-raspberry-pi-5)
|
|
- [Coral Dual Edge TPU (m.2 E key)](https://www.coral.ai/products/m2-accelerator-dual-edgetpu)
|
|
- Raspi Official 5A Power Supply
|
|
- Raspi active cooler
|
|
|
|
## Setup
|
|
|
|
### Most important sources used
|
|
|
|
[coral.ai](https://www.coral.ai/docs/m2/get-started/#requirements)
|
|
[Jeff Geerling](https://www.jeffgeerling.com/blog/2023/pcie-coral-tpu-finally-works-on-raspberry-pi-5)
|
|
[Frigate NVR](https://docs.frigate.video)
|
|
|
|
### Raspberry Pi OS
|
|
|
|
I used the Raspberry Pi Imager to flash the latest Raspberry Pi OS Lite to a SD Card.
|
|
|
|
Needs to be Debian Bookworm.\
|
|
Needs to be the full arm64 image (with desktop), otherwise you will get into camera driver hell.
|
|
{: .notice}
|
|
|
|
Settings applied:
|
|
|
|
- used the default arm64 image (with desktop)
|
|
- enable custom settings:
|
|
- enable ssh
|
|
- set wifi country
|
|
- set wifi ssid and password
|
|
- set locale
|
|
- set hostname: airaspi
|
|
|
|
### update
|
|
|
|
This is always good practice on a fresh install. It takes quite long with the full os image.
|
|
|
|
```zsh
|
|
sudo apt update && sudo apt upgrade -y && sudo reboot
|
|
```
|
|
|
|
### prep system for coral
|
|
|
|
Thanks again @Jeff Geerling, this is completely out of my comfort zone, I rely on people writing solid tutorials like this one.
|
|
|
|
```zsh
|
|
# check kernel version
|
|
uname -a
|
|
```
|
|
|
|
```zsh
|
|
# modify config.txt
|
|
sudo nano /boot/firmware/config.txt
|
|
```
|
|
|
|
While in the file, add the following lines:
|
|
|
|
```config
|
|
kernel=kernel8.img
|
|
dtparam=pciex1
|
|
dtparam=pciex1_gen=2
|
|
```
|
|
|
|
Save and reboot:
|
|
|
|
```zsh
|
|
sudo reboot
|
|
```
|
|
|
|
```zsh
|
|
# check kernel version again
|
|
uname -a
|
|
```
|
|
|
|
- should be different now, with a -v8 at the end
|
|
|
|
edit /boot/firmware/cmdline.txt
|
|
|
|
```zsh
|
|
sudo nano /boot/firmware/cmdline.txt
|
|
```
|
|
|
|
- add pcie_aspm=off before rootwait
|
|
|
|
```zsh
|
|
sudo reboot
|
|
```
|
|
|
|
### change device tree
|
|
|
|
#### wrong device tree
|
|
|
|
The script simply did not work for me.
|
|
|
|
maybe this script is the issue?
|
|
i will try again without it
|
|
{: .notice}
|
|
|
|
```zsh
|
|
curl https://gist.githubusercontent.com/dataslayermedia/714ec5a9601249d9ee754919dea49c7e/raw/32d21f73bd1ebb33854c2b059e94abe7767c3d7e/coral-ai-pcie-edge-tpu-raspberrypi-5-setup | sh
|
|
```
|
|
|
|
- Yes it was the issue, wrote a comment about it on the gist
|
|
[comment](https://gist.github.com/dataslayermedia/714ec5a9601249d9ee754919dea49c7e?permalink_comment_id=4860232#gistcomment-4860232)
|
|
|
|
What to do instead?
|
|
|
|
Here, I followed Jeff Geerling down to the T. Please refer to his tutorial for more information.
|
|
|
|
In the meantime the Script got updated and it is now recommended again.
|
|
{: .notice}
|
|
|
|
```zsh
|
|
# Back up the current dtb
|
|
sudo cp /boot/firmware/bcm2712-rpi-5-b.dtb /boot/firmware/bcm2712-rpi-5-b.dtb.bak
|
|
|
|
# Decompile the current dtb (ignore warnings)
|
|
dtc -I dtb -O dts /boot/firmware/bcm2712-rpi-5-b.dtb -o ~/test.dts
|
|
|
|
# Edit the file
|
|
nano ~/test.dts
|
|
|
|
# Change the line: msi-parent = <0x2f>; (under `pcie@110000`)
|
|
# To: msi-parent = <0x66>;
|
|
# Then save the file.
|
|
|
|
# Recompile the dtb and move it back to the firmware directory
|
|
dtc -I dts -O dtb ~/test.dts -o ~/test.dtb
|
|
sudo mv ~/test.dtb /boot/firmware/bcm2712-rpi-5-b.dtb
|
|
```
|
|
|
|
Note: msi- parent sems to carry the value <0x2c> nowadays, cost me a few hours.
|
|
{: .notice}
|
|
|
|
### install apex driver
|
|
|
|
following instructions from [coral.ai](https://coral.ai/docs/m2/get-started#2a-on-linux)
|
|
|
|
```zsh
|
|
echo "deb https://packages.cloud.google.com/apt coral-edgetpu-stable main" | sudo tee /etc/apt/sources.list.d/coral-edgetpu.list
|
|
|
|
curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
|
|
|
|
sudo apt-get update
|
|
|
|
sudo apt-get install gasket-dkms libedgetpu1-std
|
|
|
|
sudo sh -c "echo 'SUBSYSTEM==\"apex\", MODE=\"0660\", GROUP=\"apex\"' >> /etc/udev/rules.d/65-apex.rules"
|
|
|
|
sudo groupadd apex
|
|
|
|
sudo adduser $USER apex
|
|
```
|
|
|
|
Verify with
|
|
|
|
```zsh
|
|
lspci -nn | grep 089a
|
|
```
|
|
|
|
- should display the connected tpu
|
|
|
|
```zsh
|
|
sudo reboot
|
|
```
|
|
|
|
confirm with, if the output is not /dev/apex_0, something went wrong
|
|
|
|
```zsh
|
|
ls /dev/apex_0
|
|
```
|
|
|
|
### Docker
|
|
|
|
Install docker, use the official instructions for debian.
|
|
|
|
```zsh
|
|
curl -fsSL https://get.docker.com -o get-docker.sh
|
|
sudo sh get-docker.sh
|
|
```
|
|
|
|
```zsh
|
|
# add user to docker group
|
|
sudo groupadd docker
|
|
sudo usermod -aG docker $USER
|
|
```
|
|
|
|
Probably a source with source .bashrc would be enough, but I rebooted anyways
|
|
{: .notice}
|
|
|
|
```zsh
|
|
sudo reboot
|
|
```
|
|
|
|
```zsh
|
|
# verify with
|
|
docker run hello-world
|
|
```
|
|
|
|
### set docker to start on boot
|
|
|
|
```zsh
|
|
sudo systemctl enable docker.service
|
|
sudo systemctl enable containerd.service
|
|
```
|
|
|
|
### Test the edge tpu
|
|
|
|
```zsh
|
|
mkdir coraltest
|
|
cd coraltest
|
|
sudo nano Dockerfile
|
|
```
|
|
|
|
Into the new file, paste:
|
|
|
|
```Dockerfile
|
|
FROM debian:10
|
|
|
|
WORKDIR /home
|
|
ENV HOME /home
|
|
RUN cd ~
|
|
RUN apt-get update
|
|
RUN apt-get install -y git nano python3-pip python-dev pkg-config wget usbutils curl
|
|
|
|
RUN echo "deb https://packages.cloud.google.com/apt coral-edgetpu-stable main" \
|
|
| tee /etc/apt/sources.list.d/coral-edgetpu.list
|
|
RUN curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -
|
|
RUN apt-get update
|
|
RUN apt-get install -y edgetpu-examples
|
|
```
|
|
|
|
```zsh
|
|
# build the docker container
|
|
docker build -t "coral" .
|
|
```
|
|
|
|
```zsh
|
|
# run the docker container
|
|
docker run -it --device /dev/apex_0:/dev/apex_0 coral /bin/bash
|
|
```
|
|
|
|
```zsh
|
|
# run an inference example from within the container
|
|
python3 /usr/share/edgetpu/examples/classify_image.py --model /usr/share/edgetpu/examples/models/mobilenet_v2_1.0_224_inat_bird_quant_edgetpu.tflite --label /usr/share/edgetpu/examples/models/inat_bird_labels.txt --image /usr/share/edgetpu/examples/images/bird.bmp
|
|
```
|
|
|
|
Here, you should see the inference results from the edge tpu with some confidence values.\
|
|
If it ain't so, safest bet is a clean restart
|
|
|
|
### Portainer
|
|
|
|
This is optional, gives you a browser gui for your various docker containers
|
|
{: .notice}
|
|
|
|
Install portainer
|
|
|
|
```zsh
|
|
docker volume create portainer_data
|
|
docker run -d -p 8000:8000 -p 9443:9443 --name portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce:latest
|
|
```
|
|
|
|
open portainer in browser and set admin password
|
|
|
|
- should be available under <https://airaspi.local:9443>
|
|
|
|
### vnc in raspi-config
|
|
|
|
optional, useful to test your cameras on your headless device.
|
|
You could of course also attach a monitor, but i find this more convenient.
|
|
{: .notice}
|
|
|
|
```zsh
|
|
sudo raspi-config
|
|
```
|
|
|
|
-- interface otions, enable vnc
|
|
|
|
### connect through vnc viewer
|
|
|
|
Install vnc viewer on mac.\
|
|
Use airaspi.local:5900 as address.
|
|
|
|
### working docker-compose for frigate
|
|
|
|
Start this as a custom template in portainer.
|
|
|
|
Important: you need to change the paths to your own paths
|
|
{: .notice}
|
|
|
|
```yaml
|
|
version: "3.9"
|
|
services:
|
|
frigate:
|
|
container_name: frigate
|
|
privileged: true # this may not be necessary for all setups
|
|
restart: unless-stopped
|
|
image: ghcr.io/blakeblackshear/frigate:stable
|
|
shm_size: "64mb" # update for your cameras based on calculation above
|
|
devices:
|
|
- /dev/apex_0:/dev/apex_0 # passes a PCIe Coral, follow driver instructions here https://coral.ai/docs/m2/get-started/#2a-on-linux
|
|
|
|
volumes:
|
|
- /etc/localtime:/etc/localtime:ro
|
|
- /home/aron/frigate/config.yml:/config/config.yml # replace with your config file
|
|
- /home/aron/frigate/storage:/media/frigate # replace with your storage directory
|
|
- type: tmpfs # Optional: 1GB of memory, reduces SSD/SD Card wear
|
|
target: /tmp/cache
|
|
tmpfs:
|
|
size: 1000000000
|
|
ports:
|
|
- "5000:5000"
|
|
- "8554:8554" # RTSP feeds
|
|
- "8555:8555/tcp" # WebRTC over tcp
|
|
- "8555:8555/udp" # WebRTC over udp
|
|
environment:
|
|
FRIGATE_RTSP_PASSWORD: "******"
|
|
```
|
|
|
|
### Working frigate config file
|
|
|
|
Frigate wants this file wherever you specified earlier that it will be.\
|
|
This is necessary just once. Afterwards, you will be able to change the config in the gui.
|
|
{: .notice}
|
|
|
|
```yaml
|
|
mqtt:
|
|
enabled: False
|
|
|
|
detectors:
|
|
cpu1:
|
|
type: cpu
|
|
num_threads: 3
|
|
coral_pci:
|
|
type: edgetpu
|
|
device: pci
|
|
|
|
cameras:
|
|
cam1: # <++++++ Name the camera
|
|
ffmpeg:
|
|
hwaccel_args: preset-rpi-64-h264
|
|
inputs:
|
|
- path: rtsp://192.168.1.58:8900/cam1
|
|
roles:
|
|
- detect
|
|
cam2: # <++++++ Name the camera
|
|
ffmpeg:
|
|
hwaccel_args: preset-rpi-64-h264
|
|
inputs:
|
|
- path: rtsp://192.168.1.58:8900/cam2
|
|
roles:
|
|
- detect
|
|
detect:
|
|
enabled: True # <+++- disable detection until you have a working camera feed
|
|
width: 1280 # <+++- update for your camera's resolution
|
|
height: 720 # <+++- update for your camera's resolution
|
|
```
|
|
|
|
### mediamtx
|
|
|
|
install mediamtx, do not use the docker version, it will be painful
|
|
|
|
double check the chip architecture here, caused me some headache
|
|
{: .notice}
|
|
|
|
```zsh
|
|
mkdir mediamtx
|
|
cd mediamtx
|
|
wget https://github.com/bluenviron/mediamtx/releases/download/v1.5.0/mediamtx_v1.5.0_linux_arm64v8.tar.gz
|
|
|
|
tar xzvf mediamtx_v1.5.0_linux_arm64v8.tar.gz && rm mediamtx_v1.5.0_linux_arm64v8.tar.gz
|
|
```
|
|
|
|
edit the mediamtx.yml file
|
|
|
|
### working paths section in mediamtx.yml
|
|
|
|
```yaml
|
|
paths:
|
|
cam1:
|
|
runOnInit: bash -c 'rpicam-vid -t 0 --camera 0 --nopreview --codec yuv420 --width 1280 --height 720 --inline --listen -o - | ffmpeg -f rawvideo -pix_fmt yuv420p -s:v 1280x720 -i /dev/stdin -c:v libx264 -preset ultrafast -tune zerolatency -f rtsp rtsp://localhost:$RTSP_PORT/$MTX_PATH'
|
|
runOnInitRestart: yes
|
|
cam2:
|
|
runOnInit: bash -c 'rpicam-vid -t 0 --camera 1 --nopreview --codec yuv420 --width 1280 --height 720 --inline --listen -o - | ffmpeg -f rawvideo -pix_fmt yuv420p -s:v 1280x720 -i /dev/stdin -c:v libx264 -preset ultrafast -tune zerolatency -f rtsp rtsp://localhost:$RTSP_PORT/$MTX_PATH'
|
|
runOnInitRestart: yes
|
|
```
|
|
|
|
also change rtspAddress: :8554\
|
|
to rtspAddress: :8900\
|
|
Otherwise there is a conflict with frigate.
|
|
|
|
With this, you should be able to start mediamtx.
|
|
|
|
```zsh
|
|
./mediamtx
|
|
```
|
|
|
|
If there is no error, you can verify your stream through vlc under rtsp://airaspi.local:8900/cam1 (default would be 8554, but we changed it in the config file)
|
|
|
|
### Current Status
|
|
|
|
I get working streams from both cameras, sending them out at 30fps at 720p.
|
|
frigate, however limits the display fps to 5, which is depressing to watch, especially since the tpu doesnt even break a little sweat.
|
|
|
|
Frigate claime that the TPU is good for up to 10 cameras, so there is headroom.
|
|
|
|
The stram is completely errant and drops frames left and right. I have sometimes seen detect fps of 0.2, but the TPU speed should definitely not be the bottleneck here. Maybe attach the cameras to a separate device and stream from there?
|
|
|
|
The biggest issue here is that the google folx seems to have abandoned the coral, even though they just released a new piece of hardware for it.
|
|
Their most RECENT python build is 3.9.
|
|
Specifically, pycoral seems to be the problem there. without a decent update, I will be confined to debian 10, with python 3.7.3.
|
|
That sucks.
|
|
There are custom wheels, but nothing that seems plug and play.
|
|
|
|
About the rest of this setup:
|
|
The decision to go for m.2 E key to save money, instead of spending more on the usb version was a huge mistake.
|
|
Please do yourself a favor and spend the extra 40 bucks.
|
|
Technically, its probably faster and better with continuous operation, but i have yet to feel the benefit of that.
|
|
|
|
### TODOs
|
|
|
|
- add images and screenshots to the build log
|
|
- Check whether vdo.ninja is a viable way to add mobile streams. then Smartphone stream evaluation would be on the horizon.
|
|
- Bother the mediamtx makers about the libcamera bump, so we can get rid of the rpicam-vid hack.
|
|
I suspect there is quirte a lot of performance lost there.
|
|
- tweak the frigate config to get snapshots and maybe build an image / video database to later train a custom model.
|
|
- worry about attaching an external ssd and saving the video files on it.
|
|
- find a way to export the landmark points from frigate. maybe send them via osc like in pose2art?
|
|
- find a different hat that lets me access the other TPU? I have the dual version, but can currently only acces 1 of the 2 TPUs due to hardware restrictions.
|