モバイルエンジニアの視点からGithub Copilotを触る

このエントリはTimee Advent Calendar 2023 シリーズ1 12/21の記事です。昨日は@atantomotimeeさんの「静かなSquadの進化: エンゲージメントが高まるきっかけ」でした。


こんにちは、タイミーでAndroidエンジニアをしているはるです。

みなさんはGithub Copilotを使っていますか?私は導入していますがあまり使いこなせていません……存在しないActivityへのIntentを発行したり、変なことをしでかしてくれることが多く、まだガッツリと使うことができていません。そんな中で、周りのエンジニア(主にバックエンドエンジニア)からはとても良いぞ!と言う声が聞こえてくるので、羨ましいなーと思っているところです。

しかし、いくつかAndroidエンジニアでもGithub Copilotを活用できるシーンを発見したのでご紹介したいと思います。

Github Copilotをモバイルでも活用できるシーン

単純な置換だけでは出来ないようなリファクタリング

たとえば、Android14対応する中でActivityのメソッドからOnBackPressedDispatcherを利用した実装への変更をするケースを思い浮かべてみてください。

この場合ではGithub Copilotを上手に使うことができます。

Activityのメソッドを残したままOnBackPressedDispatcherを使った実装を書き始めると、勝手にActivity側の処理を内包したDispatcherを書いてくれます。

これは正直驚きました。Tabを押すだけで各画面のOnBackPressedDispatcherが出来上がっていくので、とても便利でした。

AndroidAPIをシンプルに叩くだけのシーン

このシーンでも、同様にGithub Copilotの恩恵に預かることができました。ほとんどAndroid Developerのドキュメント通りに書くだけ、といったシーンではとても重宝します。

このほかにもいろいろなシーンで有効活用できると思うのですが、まだなかなか発見できていません。ほかにもこう言うときに便利!といったシーンがあれば、ぜひ教えていただけると嬉しいです。

Github Copilotが苦手としているシーン

逆に、このようなシーンではうまくサジェストしてくれませんでした。

マルチモジュール構成で、他のモジュールを参照している部分

タイミーではマルチモジュール構成でAndroid版のアプリを開発していますが、この場合はまだうまく参照先のコードを見てくれないようで、正しくサジェストしてくれることは少なかったです。

どうにかして他のモジュールも参照した上でサジェストしてくれるようになって欲しいのですが、果たしてその時は来るのか……

--

これからもGithub Copilotを使い続けて、その進化に気づいていくような日常を送れれば楽しいなあと思っています。これからに期待!

DTM歴長かったけど初めてアルバム出した話

なんだか感慨深いのでメモ。 f:id:haru2036:20211008200652p:plain 1st Album "Discover" 発売中です!

go.haru2036.com

原体験

私が初めてDTMのようなことをしたのっていつだっけと思った時に、記憶に残っている中では小学生の時まで遡ります。

YAMAHAの「らくらく作曲名人」みたいな名前のソフトを使って適当に遊んでただけだったような気がするんですが、小学校に通っている間はずっとピアノを習っていました。

そして中高生時代に自由に使える(家族共用じゃない)PC環境を手に入れて、順調にパソコンだいすきオタクへの道を歩んでいくわけですが、そんな時に同人CDとしてリリースされていたトランスのクロスフェードサンプル音源を聴いてトランスにハマりだしたような気がします。 そこから結構悩んだ挙句FL Studio Signature Bundle(バージョンは覚えてない)を購入して、本格的なDTM環境を整えて曲を作るという趣味にハマったわけですが、如何せん他にも趣味が多かったのでお金も時間もローテーションしながらやりたい時にやりたい趣味をやっていたため、上達スピードとしてはそんなに速くなかったような覚えがあります。

高校時代はほんの少し軽音楽部でベース弾いたりもしてたんですが、当時Audio IFなんてものは持ってなかったので自分の曲に自分の演奏を録音するという発想すら浮かんでませんでした。 そんなわけで打ち込みメインの制作が今でもメインですが、大学に入ってやっと同好の士を見つけることとなります。

比較的最近の制作事情

そんなこんなで、大学時代DTMをする友人を見つけたり、大学サークル内でもそういう活動をしたりしていたのですが、みんなが凄すぎて逆に自信を無くしてました。

結果としてあんまり音源を表に出さない氷河期時代が始まってしまったんですが、これはひとえに自分の考え方がまずいですね、はい……

それでも細々と曲を作ったりしているうちに、だんだんと道具も揃い、その使い方も覚え、クオリティもだんだんと上がってきたんだと思っています。VRChatを始めてから、人にちらっと自分の曲を聞いてもらってダイレクトに感想をもらえる環境が手に入ったことで、自分の自信のなさというのも段々と和らいできました。

そんな中音楽以外の全く関係ないアバター制作という(これまた自分のスキルセットがなかなか活かしづらいと感じてたけどかなり活かせた)ジャンルで今度は同人サークルメンバーとして共同制作して作品を発表する中で、そういった同人活動的なものの楽しさを初めて知ることになりました。(ステマ:「フェヰリル」発売中です!ぜひぜひ!)

ついでに黒色さんの「ジャケ絵描いたるから出せ!」というとてもパワフルな後押しを得て、やっとリリースとなりました。

Boothで購入したりBandcampで聴いてくださった方がどう感じるかはちょっと気になりますが、それはさておき自分としてはこのアルバムの曲たちは色々な意味で特別なものになりました。

VRChat界隈の人達がやたらクリエイティブなのは何故なのだろうかと思うことは多いのですが、実際にこの流れを体験するとわかった気がします。 場所の制約を飛び越えて、色々な人に直接作ったものを見せることができるし、リアルタイムに感想をもらうこともできる。こんなにポジティブな外発的モチベーションは他にはあまりないと思います。

(あ、VRC歴もそれなりに長かったわ…ずっと不思議に思ってたんだよなあ…)

まとm(まりません)

そんなこんなでこれまでの音楽的な諸々の流れからちょっとだけ飛び出すことができたはるの、新しいアルバムです。もしよかったら聴いてください!

go.haru2036.com

話の中に出てきたアバターの「フェヰリル」はこちら!

booth.pm

HHKB Hybridを買った

ついに世代交代。

実のところ、HHKB Pro2でも全く問題なく使えていたものの、クラムシェルモード(と巷では言うらしい)でMacBook Pro 16inchを使うケースがふえてきた(Flutter開発時にiOS端末にデプロイしたりすることを考えるとMacも使いたい)ために、いちいちケーブル引っこ抜いてDIPスイッチパチパチ切り替えて別のマシンにケーブルをつなぐのも結構面倒だし、とはいえキーボードを机の上に2台以上置きたくないし……という葛藤の末、MNGしてしまったのでした。

USB接続のWindows機を使いたいときはFn+Ctrl+0で接続先をUSBにした後、Fn+Ctrl+WでWindowsモードにモードを変更しなければならず、その際うっかり誤爆するとブラウザのタブが閉じられてしまうことがある以外は特に不満なし。 MacにつなぐときもFn+Ctrl+1でBT接続先その1のMacにつないで、Fn+Ctrl+MでMac向けのキー配置に切り替えることによって快適に使うことができた。

ツイートの写真にもあるように、謎に調子に乗ってカラーキートップを一緒に買ってしまったので、EscとCtrlそれぞれを新旧二台のHHKBに取り付けてみた。キャラ性が付加された感じがしてこれはこれでなかなか楽しいかもしれない。

しかし、余ったHHKB Pro2どうしよう……バリバリ現役で使えるのでもったいないが、似たような経緯でRealforceテンキーレスとMajestouch黒軸テンキーレスが転がってるので同じような運命をたどってしまいそうで悩み中……

一度死んだVRCSDK2のワールド(と、それを使うイベント)をVRCSDK3でゴリ押し再構築した話

この記事は「VRChat Advent Calendar 2020 (https://adventar.org/calendars/5102)」19日目の記事です。 お久しぶりです(?)はるです。

私は以前VRChat上でVRC-LT(https://vrc-lt.github.io/)というLT会を開催していたのですが、この会は今年半ばごろにSDK2の同期関連の挙動が変わってワールドが動作しなくなってしまったのが原因で、しばらく無期限延期状態になっていました。

流石にワールドのロジックを記述するのにSDK2のTriggerベースではこの先メンテしきれないし、SDK3にはVRC_Panoramaのような画像を取得してきて表示するような機能を持ったComponentは存在しないし、どうしよう……と思っていたのですが、先日変なやる気を起こしてゴニョゴニョしていたら案外できるのでは?という気持ちになってきたので、その話を書きたいと思います。

この記事に関連するリポジトリhttps://github.com/vrc-lt にあります。

全体的に突貫工事でガバガバなのはゆるして。

もともとのワールド

在りし日のVRC-LT on VRCSDK2の様子は以下のWebページに動画やスライドへのリンクとしてアーカイブされていますので、そこを見てもらえると手っ取り早いです。スライド画像のページめくりが同期しており、スライドを逐次読み込んだり、発表順に合わせてWeb管理画面から並び替えることができました。

https://vrc-lt.github.io/past-events.html

これらはVRChat Build 820くらいからまともに動かなくなってしまったので、SDK3で組み直せるようになるまでは一旦置いておこう……となってしまいました。

動画をコマ送りする

ときは流れてSDK3のワールドも一般的になり、C#ライクなUdonSharpが開発され、そしてSDK3にも動画プレイヤーが実装されました。

しかしVRC_Panoramaのような静止画を取得できるコンポーネントはいつまで待っても追加されないので、今あるものでどうにかならんかなーとぼんやり考えるようになりました。[*1]

スライドを外部から取得してきて表示すること自体は、とても単純なアイデアで実現できそうに感じました。一定の時間で画面が切り替わる動画を再生させて、動画プレイヤーとしては常に一時停止の状態のまま再生位置を変化させれば良いからです。

このやり方は実際に機能しました。

(ワールド自体も新たに作り直したので、ProBuilderを使ってみてうれしくなっている図)

VRCSDK3を触るのはこれが初めてだったので、同期などのUdonやUdonSharpに特有の概念がどんなものなのかを探るのが最も手間がかかるポイントでした。具体的には以下のようなポイントでつまづきました。

  • [UdonSynced] がついた変数の扱い方
    • 変数に値を代入する事ができるClientをOwnerのみに限って、それ以外のClientは原則更新しない
  • OnDeserialization() の動作
    • UdonSyncedな変数が更新されたら呼ばれる(どれが更新されたかはわからない)
      • ローカルにUdonSyncedな値と対応する変数を持っておいて、それと比較して変更を検知する
      • 変更が検知されたらローカルの値を更新するとともに必要ならローカルのComponentを更新する

UdonSharpでは変数を定義する際に、[UdonSynced] をつけることによって、値が同期されるようになります。Syncedな変数の場合、値が代入されると他のクライアントでも値が新しいものに更新され、更新されたことを通知するためにOnDeserialization()というメソッドが呼ばれます。

Syncedな変数にすべてのクライアントが値を代入するような形を取るとこの動作が何度も起きてしまって収拾がつかなくなりそうだったので、Owner以外のクライアントでは値を更新せず、他のクライアントは値の更新を受けてそれぞれのクライアント内での状態をそれに合わせて更新するというやり方が広く使われているようです。

スライド用プレイヤーを実装するときに参考にしていたUSharpVideoPlayerでもこの方法で再生開始位置等を同期していたのでこれが一般的なのかなと思っていますが、他にもカスタムイベントを送るなどの方法を用いて他のClientと通信することができるようです。

実際、この方法でトラブルが多い状態ではありつつも昨日のVRC-LT #8-alphaを一応開催できたので、今のところはこれが一番やりやすい方法なのかなーと思っています。

再生用にスライドを動画に変換する

あとは、スライドのPDF等を動画に変換してYoutube等にアップロードしてもらうだけです。

動画への変換自体はffmpegなどで行うことができますが、発表者に逐一ffmpegのインストールや使い方の確認をお願いするのも申し訳ないので、そのような準備をせずに変換できる方法が必要でした。

VRC-LTでは、発表者に専用Discordサーバーに参加してもらっており、そこで連絡をとっています。

そこで、PDFが添付されたMentionを受け取ると動画に変換するDiscord Botを用意して運用することにしました。 f:id:haru2036:20201214211523p:plain

Discord Bot向けのライブラリがあって、以前から興味のあった言語であるRustを使用して書いてみました(内部的にはxpdfとffmpegを呼んでるだけなのでRustっぽさはあまりない気もします……)。それをDockerイメージに固めて適当にデプロイしています。

Discordでやり取りをしているという前提がある現在のVRC-LTでは、こうした方法で動画の変換を行うことができるので発表者側から見てもとそこまで煩雑ではなく、動画さえ用意できれば飛び入り参加も可能なので、一応やってやれないことはないかなーと思っています。

開催する

各発表者のアバターのサイズによってスライドの操作系が使いづらくなっちゃったりとか、人数が集まるとまともにページが送れなくなるみたいな実際やらないとわからないような修正ポイントが山程見つかったので、Alpha版としての開催は正解だったなーと思っています。ひとまずトラブルも有りつつすべての発表者が発表を終えることができたので、次までに今回引っかかったところを治せるだけ直してBeta版をやろうかと思っています……(意識が低い)

おわりに

ふたたびVRChat上でLT会を行えるような状態にはなったと思うので、これからまたイベントを開催できるといいなと思っています。もしよろしければご参加ください。

https://vrc-lt.github.io/

*1: Cannyでリクエストしたときは、「Dynamic Imageという名前でもっと一般化した方法を用意するよ!お楽しみに!(意訳)」というコメントとともにチケットがクローズされているので、そのうちできるようになると思います

お家くらうど kubernetes編

突然お家にkubernetesクラスタが欲しくなったのでやってみたメモ(怪文書)

やったこと

  • ubuntuVMをいくつか立てる
  • kubeadmを入れる
  • masterのVMでkubeadm init
  • それ以外のVMで紐付けるやつ(忘れた)する
  • ホスト名変え忘れてたので変える
  • kubeadm resetしてinitからやりなおし
  • 適当にビルドしたイメージを適当に立てたコンテナレジストリにpush
  • podの設定でそれを参照
  • kubectl create
  • リブートしたらswapがまたonになっててkubeletがコケてたので直した

きょうはここまで

• 雑にkubeadmを使い雑にk8sが立った • swap入ってるとコケる • コンテナイメージはまだちゃんとおける場所がない • Volumeの扱い方は要検討 • Haskell stackのイメージはでかすぎる • ローカルで使うだけならEndpointの定義で一応外に行ける

来週つづきできるかなあ……

ベースステーションを支える技術

ノリと勢いで我が家のHTC Vive ベースステーションの固定方法を紹介 ふと思い立ったので自宅のHTC Viveベースステーションの固定方法をメモっておくことにしたので書きます。 一応全く壁に穴開けたりせず、三脚とか使ったりもせずに固定できているので、結構うまくいってるんじゃないかなーと我ながら思ってたり。

TL;DR

  • もとの部屋の環境をうまく使おうず
  • 長方形の部屋なら長辺をうまく使って正方形のスペースを確保しようず

カーテンレール

ちょうどいい場所にカーテンレールがあったので、カーテンレールの上にベースステーション付属の壁用金具を載せて結束バンドでくくりつけました。かなり安定しているのでカーテンレールがいい感じの場所にあったら第一候補になりそう。

突っ張りメタルラック

収納がなかったので突っ張りメタルラックを買いました。そのときに模様替えをしたのでカーテンレールに付けたベースステーションの対角線上にメタルラックの足が来るようにして設置し、天井付近にベースステーションの金具をくくりつけてます。

少しスペースに余裕があって、部屋の長辺に余ったスペースがある場合、この手はかなり有効だと思います。

レイアウト

長方形の6帖の部屋に机など諸々を置き、残ったスペースが正方形になるようにしています。 これによってSteamVRの設定画面によれば2.0m*2.0mのスペースが確保できているようです。

三脚を使ったりすると三脚の足のぶんだけ使えないスペースが出てきてしまいますが、カーテンレールや突っ張りによる設置だとスペースをフルに使うことができるので良いと思います。

ただ、結束バンドだけで固定してるとベースステーションの起動時にビビりが発生することがあるのでうまい具合に防振ゴムなどを挟む必要はありそうです。

引っ越したい、もののまだイケてる間取りの部屋が見つからず……

お手軽に出来合いのものを組み合わせて赤外線リモコン操作する(Google Homeもあるよ!)

この記事はCPS Lab Advent Calenderの18日目の記事です。 17日目は「ゲームパッドをMIDIコントローラーとして使おうとした」でした。

こんにちは、赤外線リモコンの機器ってなかなか多いですよね。こっちはHTC Viveを設置してしまったものだからベースステーションから出る赤外線で家中のリモコンの危機です。

さて、赤外線リモコンで操作できる機器は例えばどんなものがあるでしょう。まずエアコン、ちょっと高いPCのディスプレイ、LEDシーリングライト……

色々あるのですが、今回はLEDシーリングライトを操作できるようにしました。しかも強い先人たちの築き上げたリソースをフル活用したら、殆どコードを書かずに実現できてしまいました。(しかしお手軽ではあるものの微妙な点もたくさん有りますのであしからず)

使ったもの

ESP8266-HTTP-IR-Blaster

実際の赤外線を発光する部分はESP-WROOM-02に接続した赤外線LEDから行います。 雑にユニバーサル基板上に実装しました。汚すぎてお見せできません…… まず最初の先人の成果物をまるっと利用させて頂くポイントがこちら

github.com

このスケッチでは赤外線受光素子からの赤外線パターンの記録と指定したパターンの発光を無線LAN経由から行うことができます。

ここまでcloneしてきて書き込むだけ。LAN内からは自由自在に赤外線リモコンとして操作できるようになりました。さて、次はどうしましょう?

timer(systemd)

最初に一番やりたかったことである決まった時間に照明をつけたり消したりをできるようにしました。 無駄に大掛かりだと自分でもおもっているのですが、自宅で動いているサーバのtimerタスクでESP-WROOM-02に決まった時間にHTTPリクエストを送るようにしました。 これによって、朝目が覚める時には明るい部屋になっている上に、そろそろ寝ないといけない時間帯には強制的に照明が消えます。 悩みの種であった睡眠リズムが若干改善するかもしれません。

Google Home

さて、その後Google Homeを購入したので、こいつからも操作できたら楽しいよねと思うようになりました。 しかし、Google Home経由で操作するにはDialogFlowにしろIFTTTにしろいっぺん外に出てから戻ってくるような通信経路になります。 今回はお手軽に何も考えず適当にやりたいことを実現するのが趣旨なので、もっといい方法あるんじゃないかとか思いつつ自宅IPにDDNSのアドレスを設定し自宅鯖にnginxを立ててLet's Encryptで証明書を取得して、nginxで外からの通信を受けることにしました。

とりあえずSSLBASIC認証を設定して(IFTTTだとBASIC認証しか使えなかった気が)、IFTTTのWebHookでそのまま自宅に返ってくるような感じにしました。

反応しない

冒頭でも挙げたのですが、HTC Viveが起動している間はベースステーションが部屋中に赤外線を照射するため、赤外線リモコンが一切使えなくなります。 何度もこれで照明のコントロールができずあれーおかしいなーとか言いながら数分間立ち尽くしてました。終了すれば普通に使えるし諦めました。

まとめ

とりあえずお手軽に照明をコントロールしてみましたが、ぶっちゃけ融通が聞かないと感じることも多くこの用途ならラズパイかなんかで自前実装するほうが色々コンパクトにできて楽かもしれません。

何も考えずにググるだけでやるとこうなるよ、という例ということで見ていただけると幸いです。でも何気に実用的に仕上がったのでやって見る価値はあると思いました。