SDでは面倒だ、Octoprintを入れよう

電脳

Octoprint-Build

IOT路線であれば Raspi ZERO w なんかを使うところであるが 2年前に挫折した。当時は rasbian の右も左も分からない状態で 始めたので迷走した。そして落ちることがよくあった。

自分の中ではインフラが落ちるのはあり得ないことなので 今回は raspi4 4GBににした。でも少しだけケチった。

SSD boot の Ubuntu Server 20.04 を作る

rasbian でブートオーダーだけ変えておく

この例はシリアルコンソールだけでインストールしている。

ドライバーは、 PL2303_64bit_install.exe を探して入れた。

配線は、

ケーブル raspi4
赤 5V VCC 接続しない
黒 GND ⑥ GND
白 RXD ⑧ TXD0
緑 TXD ⑩ RXD0
$ sudo raspi-config
boot-order をUSB からにする。

折角なのでシリアルコンソールも有効にしておく。(もう使わないけど)

5 Interfacing Option」→「P6 Serial」→「はい」と選択。
$ vcgencmd bootloader_config
[all]
BOOT_UART=0
WAKE_ON_GPIO=1
POWER_OFF_ON_HALT=0
DHCP_TIMEOUT=45000
DHCP_REQ_TIMEOUT=4000
TFTP_FILE_TIMEOUT=30000
ENABLE_SELF_UPDATE=1
DISABLE_HDMI=0
SD_BOOT_MAX_RETRIES=1
USB_MSD_BOOT_MAX_RETRIES=1
BOOT_ORDER=0xf41
     ^^^^^^^ ここが重要

Raspberry PI imager で ubuntu server 20.04 LTSを SDとSSD両方に書く。(64bit版で)

EthernetをつないでからSDでubuntuをブートする。 暫く待ってから ubuntu でログインする。

ログインしたら各種設定が終わるまでしばらく待つ。

暫く経ったあとSSDをUSBに挿してマウントする。

# mount /dev/sda1 /mnt
# cd /mnt
# zcat vmlinuz > vmlinux
# vi config.txt

[pi4]
#kernel=uboot_rpi_4.bin
max_framebuffers=2
dtoverlay=vc4-fkms-v3d
boot_delay
kernel=vmlinux
initramfs initrd.img followkernel
[pi2]
kernel=uboot_rpi_2.bin
[pi3]
kernel=uboot_rpi_3.bin
[all]
arm_64bit=1
device_tree_address=0x03000000
# The following settings are "defaults" expected to be overridden by the
# included configuration. The only reason they are included is, again, to
# support old firmwares which don't understand the "include" command.
enable_uart=1
cmdline=cmdline.txt
include syscfg.txt
include usercfg.txt

Kernelを解凍しておかないとSSDからブートしない。 以下を参照して自動的解凍される仕組みにすると良い。

raspberry pi 4 でubuntu20.04をusbブートするの巻 | ゆっくり遅報
はじめに ラズベリーパイ4はUSB3.0が追加され、ここに外部ストレージを追加するとmicrosdより高耐久で高速な環境にする事ができます。 ちなみに、どんなに高速なmicros...

ここに書いてある auto_decompress_kernel を /mnt に置く。 permission は勝手に実行形式になる。

cat <<EOT>/mnt/auto_decompress_kernel
#!/bin/bash -e
#Set Variables
BTPATH=/boot/firmware
CKPATH=$BTPATH/vmlinuz
DKPATH=$BTPATH/vmlinux
#Check if compression needs to be done.
if [ -e $BTPATH/check.md5 ]; then
    if md5sum --status --ignore-missing -c $BTPATH/check.md5; then
    echo -e "\e[32mFiles have not changed, Decompression not needed\e[0m"
    exit 0
    else echo -e "\e[31mHash failed, kernel will be compressed\e[0m"
    fi
fi
#Backup the old decompressed kernel
mv $DKPATH $DKPATH.bak
if [ ! $? == 0 ]; then
    echo -e "\e[31mDECOMPRESSED KERNEL BACKUP FAILED!\e[0m"
    exit 1
else    echo -e "\e[32mDecompressed kernel backup was successful\e[0m"
fi
#Decompress the new kernel
echo "Decompressing kernel: "$CKPATH".............."
zcat $CKPATH > $DKPATH
if [ ! $? == 0 ]; then
    echo -e "\e[31mKERNEL FAILED TO DECOMPRESS!\e[0m"
    exit 1
else
    echo -e "\e[32mKernel Decompressed Succesfully\e[0m"
fi
#Hash the new kernel for checking
md5sum $CKPATH $DKPATH > $BTPATH/check.md5
if [ ! $? == 0 ]; then
    echo -e "\e[31mMD5 GENERATION FAILED!\e[0m"
    else echo -e "\e[32mMD5 generated Succesfully\e[0m"
fi
#Exit

EOT

これができたらファイルシステムのマウントを変更する。

# umount /mnt
# mounnt /dev/sda2 /mnt
# cd /mnt/etc/apt/apt.conf.d
# cat <<EOT>/mnt/etc/apt/apt.conf.d/999_decompress_rpi_kernel
DPkg::Post-Invoke {"/bin/bash /boot/firmware/auto_decompress_kernel"; };

EOT

これでシャットダウンしてSDを抜き、ブートすればSSDからブートできる。 なお、SSDでブートすればubuntuアカウントの設定が始まるので ブートして暫く待ってから再びubuntuでログインする。

続いてSWAPも作成しておく

$ su
# dd if=/dev/zero of=/var/swapfile bs=1024 count=16M
# chmod 0600 /var/swapfile
# mkswap /var/swapfile
# swapon /var/swapfile
# swapon -s
# echo "/var/swapfile swap swap defaults 0 0" | sudo tee -a /etc/fstab
# root@pi4:/home/ubuntu# vi /etc/fstab
LABEL=writable / ext4 defaults 0 0
LABEL=system-boot /boot/firmware vfat defaults 0 1
/var/swapfile swap swap defaults 0 0

IPアドレスを固定にしておく

# cat <<EOT>/etc/netplan/99_config.yaml
network:
    #ethernets:
    #eth0:
    #        dhcp4: true
    #        optional: true
    #version: 2
    #
    wifis:
         wlan0:
            optional: true
            access-points:
             "SSID":
                    password: "xxxxxxxxxxxxx"
            dhcp4: false
            addresses: [192.168.0.200/24]
            gateway4: 192.168.0.1

EOT

#

Octoprint には必要ないが、環境を合わせる目的でいくつかPKGを追加している。

# apt update
# apt list --upgradable
# apt full-upgrade
# apt install xubuntu-desktop
# apt install net-tools
# apt install language-pack-ja
# update-locale LANG=ja_JP.UTF-8
# timedatectl set-timezone Asia/Tokyo
# systemctl set-default multi-user
# apt install build-essential
# apt install libreadline-dev libssl-dev libncurses-dev libz-dev
# apt install bridge-utils
# apt install apache2
# apt install php7.4 php7.4-fpm php7.4-mysql php7.4-mbstring \
 php7.4-xml php7.4-gd php7.4-curl libapache2-mod-php7.4 \
 graphviz php7.4
# apt install mariadb-server

シリアルケーブルを繋ぐピン配置は pinout で確認した。

# apt install pinout
# root@octopi:/etc/netplan# pinout
,--------------------------------.
| oooooooooooooooooooo J8     +====
| 1ooooooooooooooooooo        | USB
|                             +====
|      Pi Model ???V1.2          |
|      +----+                 +====
| |D|  |SoC |                 | USB
| |S|  |    |                 +====
| |I|  +----+                    |
|                   |C|     +======
|                   |S|     |   Net
| pwr        |HDMI| |I||A|  +======
`-| |--------|    |----|V|-------'

Revision           : c03112
SoC                : Unknown
RAM                : NoneMb
Storage            : MicroSD
USB ports          : 4 (excluding power)
Ethernet ports     : 1
Wi-fi              : False
Bluetooth          : False
Camera ports (CSI) : 1
Display ports (DSI): 1

J8:
   3V3  (1) (2)  5V
 GPIO2  (3) (4)  5V
 GPIO3  (5) (6)  GND
 GPIO4  (7) (8)  GPIO14
   GND  (9) (10) GPIO15
GPIO17 (11) (12) GPIO18
GPIO27 (13) (14) GND
GPIO22 (15) (16) GPIO23
   3V3 (17) (18) GPIO24
GPIO10 (19) (20) GND
 GPIO9 (21) (22) GPIO25
GPIO11 (23) (24) GPIO8
   GND (25) (26) GPIO7
 GPIO0 (27) (28) GPIO1
 GPIO5 (29) (30) GND
 GPIO6 (31) (32) GPIO12
GPIO13 (33) (34) GND
GPIO19 (35) (36) GPIO16
GPIO26 (37) (38) GPIO20
   GND (39) (40) GPIO21

本題のOctoprintを入れる

root@pi4:/etc/default# uname -a
Linux pi4 5.4.0-1032-raspi #35-Ubuntu SMP PREEMPT Fri Mar 19 20:52:40 UTC 2021 aarch64 aarch64 aarch64 GNU/Linux

Build

Octoprint はパッケージには無く、snapにはあったが動かず。
ネットを覗くと Ubuntu は、debianだからダメだとか書かれている。

そうは思わないけど、普通にビルドしてみる。

### make

$ sudo apt update
$ sudo apt install python3-pip
$ sudo pip3 install virtualenv
$ sudo cd src
$ sudo git clone https://github.com/foosel/OctoPrint.git
$ sudo cd OctoPrint
$ virtualenv venv
$ ./venv/bin/python setup.py install

実行してみる。

$ /home/ubuntu/src/OctoPrint/venv/bin/octoprint serve

http://host:5000 でアクセス可能となる。 最初はいろいろ聞かれる。

続いてカメラを組み込む。

$ sudo apt install subversion libjpeg62-dev imagemagick ffmpeg cmake
$ git clone https://github.com/jacksonliam/mjpg-streamer.git
$ cd mjpg-streamer/mjpg-streamer-experimental
$ export LD_LIBRARY_PATH=.
$ make

起動スクリプトを組み込む。

$ wget https://github.com/foosel/OctoPrint/raw/master/scripts/octoprint.init
$ wget https://github.com/foosel/OctoPrint/raw/master/scripts/octoprint.default

vi octoprint.default

ユーザとパスを書き換える。

OCTOPRINT_USER=ubuntu
DAEMON=/home/ubuntu/src/OctoPrint/venv/bin/octoprint

以下は変更なし
PORT=5000
DAEMON_ARGS="--port=$PORT"

$ sudo cp octoprint.init /etc/init.d/octoprint
$ sudo cp octoprint.default /etc/default/octoprint

$ sudo chmod +x /etc/init.d/octoprint
$ sodo /etc/init.d/octoprint start
起動できたら enableにしておく

$ sudo systemctl enable octoprint.service


アプリは一ヵ所にした方が良いかもしれないので、もう1回ビルド

# mkdir /home/app
# cd /home/app
# git clone https://github.com/foosel/OctoPrint.git
# cd Octoprint
# virtualenv OctoPrint
# ./OctoPrint/bin/python setup.py install

動かしてみる。
# /home/app/OctoPrint/Octprint/bin/octoprint serve


# wget https://github.com/foosel/OctoPrint/raw/master/scripts/octoprint.init
# wget https://github.com/foosel/OctoPrint/raw/master/scripts/octoprint.default

# vi octoprint.default
OCTOPRINT_USER=ubuntu
DAEMON=/home/app/OctoPrint/OctoPrint/bin/octoprint

以下は変更なし
PORT=5000
DAEMON_ARGS="--port=$PORT"

# cp octoprint.init /etc/init.d/octoprint
# cp octoprint.default /etc/default/octoprint

# chown -R ubuntu:ubuntu /home/app/OctoPrint

# chmod +x /etc/init.d/octoprint
# /etc/init.d/octoprint start

Octoprintは、rootでは動かない。

Octoprint から呼び出すスライサーも入れておく。

# apt install slic3r
# apt install prusa-slicer
# apt install cura-engine
# apt install v4l-utils
# apt install gpac


追加したプラグイン

  • Themeify
  • Progress Title
  • Cura Thumbnails
  • Prusa Slicer Thumbnails
  • MultiCam
  • Octolapse
  • Arc Welder
  • Slic3r –> command path : /usr/bin/prusa-slicer
  • CuraEngine Legacy –> command path : /usr/bin/CuraEngine

カメラ

$ sudo apt install subversion libjpeg62-dev imagemagick ffmpeg cmake
$ git clone https://github.com/jacksonliam/mjpg-streamer.git
$ cd mjpg-streamer/mjpg-streamer-experimental
$ export LD_LIBRARY_PATH=.
$ make

./mjpg_streamer -i "./input_uvc.so" -o "./output_http.so"

実際に動くか確認してみる。

http://IP address:8080/?action=stream

ubuntu のホームに起動スクリプトを用意する。

cat <<EOT>./webcam
#!/bin/bash
# Start / stop streamer daemon

case "$1" in
    start)
        pkill -x webcamDaemon
        ~/webcamDaemon >/dev/null 2>&1 &
        echo "$0: started"
        ;;
    stop)
        pkill -x webcamDaemon
        pkill -x mjpg_streamer
        echo "$0: stopped"
        ;;
    *)
        echo "Usage: $0 {start|stop}" >&2
        ;;
esac

EOT
cat <<EOT>./webcamDaemon
#!/bin/bash

MJPGSTREAMER_HOME=/home/ubuntu/src/mjpg-streamer/mjpg-streamer-experimental
MJPGSTREAMER_INPUT_USB="input_uvc.so"
MJPGSTREAMER_INPUT_RASPICAM="input_raspicam.so"

# init configuration
camera="auto"
#camera_usb_options="-r 640x480 -f 10"
camera_usb_options="-r 1280x720 -f 10"
camera_raspi_options="-fps 10"

if [ -e "/boot/octopi.txt" ]; then
    source "/boot/octopi.txt"
fi

# runs MJPG Streamer, using the provided input plugin + configuration
function runMjpgStreamer {
    input=$1
    pushd $MJPGSTREAMER_HOME
    echo Running ./mjpg_streamer -o "output_http.so -w ./www" -i "$input"
    LD_LIBRARY_PATH=. ./mjpg_streamer -o "output_http.so -w ./www" -i "$input"
    popd
}

# starts up the RasPiCam
function startRaspi {
    logger "Starting Raspberry Pi camera"
    runMjpgStreamer "$MJPGSTREAMER_INPUT_RASPICAM $camera_raspi_options"
}

# starts up the USB webcam
function startUsb {
    logger "Starting USB webcam"
    runMjpgStreamer "$MJPGSTREAMER_INPUT_USB $camera_usb_options"
}

# we need this to prevent the later calls to vcgencmd from blocking
# I have no idea why, but that's how it is...
# vcgencmd version

# echo configuration
echo camera: $camera
echo usb options: $camera_usb_options
echo raspi options: $camera_raspi_options

# keep mjpg streamer running if some camera is attached
while true; do
    if [ -e "/dev/video0" ] && { [ "$camera" = "auto" ] || [ "$camera" = "usb" ] ; }; then
        startUsb
    elif [ "`vcgencmd get_camera`" = "supported=1 detected=1" ] && { [ "$camera" = "auto" ] || [ "$camera" = "raspi" ] ; }; then
        startRaspi
    fi

    sleep 120
done

EOT

chmod 755 webcam
chmod 755 webcamDaemon
./webcam start
./webcam stop

手持ちのカメラはRGB、YUVモードどちらでも動いた。 動くモードの確認は、

v4l2-ctl -d /dev/video0 –list-formats-ext

で確認できる。

Octoprintの電源メニューからオン・オフできるようにする

# vi /home/.octoprint/config.yaml

system:
  actions:
    - action: streamon
      command: /home/ubuntu/webcam start
      confirm: false
      name: Start video stream
    - action: streamoff
      command: /home/ubuntu/webcam stop
      confirm: false
      name: Stop video stream

毎回悩むyamlのインデントはTABを使えない。

  • インデントにはスペース2個が多い。

コメント

タイトルとURLをコピーしました