概要
以前 RaspberryPi3B+をJoyconで操作するプログラムを作っていましたが、やっと手に入れた2Wで動かそうとすると見慣れないエラーで詰まりました。
日本系の解説サイトや公式ドキュメントには pygame.init()
で初期化してください。としか記載なく詰まっていたところ解決策を見つけたので共有します。
何が起きたか
RaspberryPi3B+で作成し当時実行確認できたプログラムが2Wで動かなかった
まず発生したエラーとその時のソースコードは以下のものです。
JoyStickの名前とボタン数は取得できているためプログラム自体に問題はないように思います。
import time
import pygame
from smbus2 import SMBus
def main():
# pygameの初期化
pygame.init()
try:
# ジョイスティックインスタンスの生成
joys = pygame.joystick.Joystick(0)
# ジョイスティックの初期化
joys.init()
print('ジョイスティックの名前:', joys.get_name())
print('ボタン数 :', joys.get_numbuttons())
except pygame.error:
print('ジョイスティックが接続されていません')
# ループ
active = True
while active:
events = pygame.event.get()
for event in events:
print(event)
time.sleep(0.1)
if __name__=="__main__":
main()
解決策
pygame.error: video system not initialized
で調べると気になる投稿が見つかりました。
#this will fool the system to think it has video access
import os
import sys
os.environ["SDL_VIDEODRIVER"] = "dummy"
上記のようにダミーのビデオアクセスを作ることで実行できるようになりました。
import time
import pygame
from smbus2 import SMBus
import os
import sys
os.environ["SDL_VIDEODRIVER"] = "dummy"
def main():
# pygameの初期化
pygame.init()
try:
# ジョイスティックインスタンスの生成
joys = pygame.joystick.Joystick(0)
# ジョイスティックの初期化
joys.init()
print('ジョイスティックの名前:', joys.get_name())
print('ボタン数 :', joys.get_numbuttons())
except pygame.error:
print('ジョイスティックが接続されていません')
# ループ
active = True
while active:
events = pygame.event.get()
for event in events:
print(event)
time.sleep(0.1)
if __name__=="__main__":
main()
おまけ
この問題に直面した時の検索では見つけられなかったのですが後日 os.environ["SDL_VIDEODRIVER"]
で検索すると面白い情報を見つけました。 私はどう足掻いても問題直面時にpygame公式Wikiのこの記事に辿り着けなかったんですが、、この方すごいです。。
DummyVideoDriver — wiki
You can use PyGame without opening a visible display (e.g. for testing, or for integrating with other frameworks that have their own displays) by using SDL environment variables before you initialise pygame. Environment variables can be set with the os.environ dict in python.
文章的に見るとpygameはそもそもディスプレイ接続前提のように読み取れてしまいますが、pygameのチュートリアル見てもそんなこと書いてないんですよね..(もし書いてたらすいません、その箇所を教えてください)