ゆるエンジニアはいろいろ遊びたい

FAエンジニアが週末にいろいろ遊ぶブログです

RaspberryPi5 RaspberryPiOS TrixieでControl Centreを開く度に認証を求められる件

2026年6月においてRasberryPiOS Trixieの最新バージョンでは、Control Centreを開く度にcups-browsed.serviceから認証を求めれるようになっています。
去年まではそんなことはなかったので、バージョンアップに伴って発生していると思われます。
この対策として、polkitのルールで認証をスキップすると解決するようです。
ターミナルで、以下を入力し、nanoエディタで新しくファイルを作成します。

sudo nano /etc/polkit-1/rules.d/49-cups-browsed.rules

内容は以下をそのまま貼り付けて、Ctl+Oで保存。
Ctl+Xで閉じます

polkit.addRule(function(action, subject) {
    if (action.id == "org.freedesktop.systemd1.manage-units" &&
        subject.isInGroup("sudo")) {
        return polkit.Result.YES;
    }
});

Polkitを再起動します

sudo systemctl restart polkit

これでOK,煩わしい認証画面が出なくなります。

ガジェット製作が面白い

3Dプリンタを買ってから気軽にいろんなものが作れて非常に重宝しております。
ここ最近ブログを更新していなかったのですが、マイコンを搭載したガジェット製作をしておりました。
今回は製作したガジェット2つをご紹介

SEED_CHAN (SEEDSTUDIO XIAO ESP32C3)


以前からスタックチャンがほしいなぁと思っていたのですが、どうやって作るかがイマイチわからず、完成品は売り切れという状況でしたので似たようなものを作ってみました。
とはいっても、カメラやマイクは搭載しておらず、フェイスデザインをまねただけのバッタもんです。

  • SeedStudio XIAO ESP32C3
  • 圧電ブザー
  • タッチスイッチ×2
  • リポバッテリー500mha

差し当って天気予報と波風情報を取得して表示できるようにしてみました。
配線がかなりギュウギュウでもう少し余裕を持たせた設計をすればよかったと後悔しました。
つぶらなお目目がかわいい

CYBER_DECK RPI (RaspberryPI 5)


始めて購入したマイコンのラズパイ5ですが、当初はホームサーバーとして運用していたのですが私の生活に常時稼働のサーバーは不要でした。
ラズパイ5は電源が5V/5Aで、通常のUSB充電器やモバイルバッテリーでは動作しないというところが最大のネックです。
また、最近は価格が高騰しており、壊れたらまた買えばいいという気軽さもなく簡単な電子工作では出番がない状態でした。
非常に高性能なマイコンですが、これ単体でAIを動かしたりするのはちょっと荷が重く、なかなか使いどころに困っていたところです。
そんな中最近よくみるサイバーデックをヒントに、ブレッドボード上での電子工作を思う存分楽しめるガジェットを作ってみようと思ったわけです。

  • Raspberry Pi5
  • 0.96インチ OLEDディスプレイ
  • タクトスイッチ×4
  • ブレッドボード

基本的にプログラミングはPCからSSH接続するのでモニターやキーボードは不要ですが、タクトスイッチとディスプレイを付けておけばオフラインでも完成したプログラムを実行したり、操作したりできるのでいいのではないかと。
なにより見た目が非常にかっこいい。
このデックにいろんなセンサーやらLEDやらを接続すると、それだけでなにやら楽しくなってきます。
ロボット製作は思った以上にお金がかかるため、今後はガジェットで遊ぶことが増えそうです。

Seed Studio XIAO ESP32C3でLチカ

ラズパイやArduinoを使って電子工作をしていく中で、ESP32というマイコンがあるという事を知り、そのうち使ってみようと思っていました。
ESP32の中でも、Seed Studio XIAO ESP32C3というマイコンは1000円くらいで購入できるリーズナブルな商品です。
今回は基本のLチカをしてみました。

パッケージからすでに小さい。

内容物

  • ESP32C3本体
  • ピンヘッダー
  • アンテナ

ピンヘッダーが付属なのは非常にありがたいですね。早速はんだ付けしました。

公式サイトにチュートリアルが公開されています。
wiki.seeedstudio.com
LEDを点灯させる際は、過電流を防止するために150Ωの抵抗を接続せよと書いています。
あいにく手元に150Ωがなかったのですが、100Ωがあったので2つを並列、1つを直列に接続して150Ωを作り、配線しました。

チュートリアルの説明はArduino IDEのバージョンが古く、最新のバージョンとは方法が違っていました。
最新バージョンのArduinoIDEでは、左側のタブにボードマネージャがあります。
そこからesp32と検索することでボードをインストールすることができます。
上部のリストボックスから他のボードとポートを選択という項目を選び、XIAO_ESP32C3のボードと、接続されたUSBのポートを選択すればOKです。
スケッチはこちら

const int led = D10;


void setup() {
  pinMode(led, OUTPUT);
}

void loop() {
  digitalWrite(led, HIGH);
  delay(1000);
  digitalWrite(led, LOW);
  delay(1000);
}

成功すればLEDが点滅します。


これまでラズパイやATOM Matrixをいじってきたため、非常にイージーに実装することができました。
さぁ、問題はこいつで何をするかですね。

VS Codeのターミナルから仮想環境に入れないときに確認する事

VS Codeでは、初期設定だとターミナルからコマンドを実行して仮想環境に入ったりができない場合があります。
スクリプトを実行する事が出来ないためらしく、設定を変更することで解決することができます。
まずはVS Codeの「表示」から「コマンドパレット」をクリックします。

Settingで検索し、「基本設定:設定(UI)を開く」をクリックします。

再度Settingで検索すると、青字でsetting.jsonで編集という項目があるため、クリックします。

末尾に、以下の内容を入力します。

"terminal.integrated.env.windows": {
"PSExecutionPolicyPreference": "RemoteSigned"
}

内容を保存してから、VS Codeを再起動します。
コマンドを入力し、スクリプトが走ることを確認します。

ShelPiがジェスチャーを理解できるようになりました

ShelPiはYOLOによる物体検出ができるため、特定のオブジェクトに対しアクションを行うといった制御が可能となっています。
よりグレードアップさせるために、手の動きを認識させてジェスチャー操作ができるか試してみました。
ChatGPTによると、MediaPipeというGoogleが提供している機械学習を用いたオープンソース・フレームワークというものがいいらしい。よくわかりませんが。
なにやらこれでハンドトラッキングができるようなので、早速試してみました。
MediaPipeは旧バージョンを使った方が簡単らしいので、仮想環境に以下のバージョンをインストールします。

pip install mediapipe==0.10.13
import cv2
import mediapipe as mp
import requests
import numpy as np

mp_hands = mp.solutions.hands
hands = mp_hands.Hands()
mp_draw = mp.solutions.drawing_utils

#カメラ映像取得
SHELPI_IP = "ShelpiのIPアドレス"
SNAPSHOT_URL = f"http://{SHELPI_IP}:8080/?action=snapshot"

def get_frame():
    r = requests.get(SNAPSHOT_URL)
    img_arr = np.frombuffer(r.content, np.uint8)
    frame = cv2.imdecode(img_arr, cv2.IMREAD_COLOR)
    return frame

while True:
    frame = get_frame()
    frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)

    results = hands.process(frame_rgb)

    if results.multi_hand_landmarks:
        if results.multi_hand_landmarks:
            for hand_idx, hand_landmarks in enumerate(results.multi_hand_landmarks):
                print(f"\n--- Hand {hand_idx} ---")

        for i, lm in enumerate(hand_landmarks.landmark):
            print(f"{i}: x={lm.x:.3f}, y={lm.y:.3f}, z={lm.z:.3f}")

        for handLms in results.multi_hand_landmarks:
            mp_draw.draw_landmarks(frame, handLms, mp_hands.HAND_CONNECTIONS)

    cv2.imshow("hand", frame)

    if cv2.waitKey(1) & 0xFF == 27:
        break

ShelPiはmjpg-streamerで映像をストリーミングしているので、それを取得して解析します。
実行すると、プレビューで手の骨格が表示され、ターミナルには各ポイントの座標が表示されます。


かなり正確に骨格をトラッキングしているのが確認できました。
各ポイントのIDですが、

このようになっていて、各ポイントの座標の位置関係を比較してジェスチャーをプログラムしました。

グッドポーズ : じたばたして喜ぶ
手を振る : バイバイする
手の平を下にする : お手をする

カメラの画角が狭くて、ロボットが動いているとなかなか認識させるのが大変でした。
広角カメラだともっといいんでしょうね。
でも、本格的なロボットになってきて満足です。

YOLOをGPUで動かしてみた

ShelPiで使っている物体検出モデルのYOLOですが、現在CPUで動作しています。
これでも全然高速なのですが、今回はGPUで動かしてみたいと思います。
GPUで動作させるためには、pytorchというものを入れる必要があるようです。

pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121
pip install ultralytics

インストールが完了したら、GPUを認識しているかチェックします。
pythonで

import torch
print(torch.cuda.is_available())
print(torch.cuda.get_device_name(0))

結果

  • True
  • NVIDIA GeForce RTX3060(自分のGPU)

となれば成功
GPUで動かすには、modelにcudaを指定するといいようです。

model = YOLO("yolov8n.pt")
model.to("cuda")
#または
results = model(frame, divice="cuda")

GPUを使っているかの確認は

nvidia-smi

で、

====================================
|Voltage     Uncorr.ECC|
|GPU-Util Compute M.|
|                       MIG M.|
====================================
|                             N/A|
|       42%          Default|
|                             N/A|

こんな感じの画面が出てきますので、このGPU-Utilの部分がYOLO実行中に増加すればGPUを使っていると判断できます。
画像1枚ではすぐ終わってしまいわからないので、動画ファイルを与えてあげるとわかりやすいです。
YOLO自体がすごく軽いので、GPUの恩恵を全く感じませんでしたが、今後他のモデルを同時に使うときに役立ちそうです。

ShelPiに視覚を実装しました

ShelPiのカメラでストリーミングした映像をメインPCで画像認識することができたので、これをShelPiに反映させてみました。

当初計画していたシステムでは、メインPCで画像認識をローカルLLMで行い、ShelPiに行動の指示をする予定でした。
ローカルLLMは画像からとるべき行動を考え、ShelPiに直接コマンドを送って制御しようというものです。
ですが、ローカルLLMでは応答速度が遅くリニアな反応が期待できません。

ロボットを制御する場合はリアルタイムで画像を認識できないと反応が遅くストレスがたまることが分かったので、LLMではなく、YOLOによる画像認識の結果を使う事にしました。
YOLOであれば、メインPCで50ms程度の速度で処理できるため、リニアな反応をさせる事ができます。

メインPCでどこまで制御するかがわりと難しく、LLMを使ってメインPC側でShelPiを制御したいという当初の計画でプログラムを作ると、画像認識して特定のオブジェクトを検出したらShelPiの動作モードを変えるフラグをjson形式で送信するようなプログラムになりました。

ところが、この方法だとShelPiの動作はメインPCに依存するので動作にかかわるプログラムが分かれてしまいます。
また、ShelPiにはカメラの他に超音波センサーが搭載されていますが、このセンサーの情報を使いたい場合、メインPC側にデータを送信しなければなりません。

このような理由からメインPC側では動作にかかわる指示はせずに、画像認識の結果のみをShelPiに出力することにしました。

いってみれば、メインPCは目としての役割のみを担うという事で、動作はShelPiに搭載されているRaspberryPi zero2Wで制御します。
YOLOの画像認識の結果、人や犬、猫などの特定のオブジェクトを認識したら、その映像をカメラの中心にとらえるように方向を調整し、超音波センサーの測定値で適切な距離まで近づきます。
適切な距離まで近づいたらコミュニケーションをさせるという制御をさせるのです。

ShelPiがとっても賢くなり、とてもかわいいです