はじめに
MAヒーローズ・リーグ Advent Calendar 2020の2日目つまりは過去の投稿です。なんかアドベントカレンダーがスカスカだったので入れておきます。とはいっても今回とれた賞とかはないので自己満足記事です。
つくったもの
つくったものはSORAJIROです。作品のクオリティはともかくとして、我ながら味のある動画ができたのではないかと思っています。とはいえ周りのレベルが高かったので表彰に行くことは難しかったですね。
とりあえず今回はSORAJIROを作る過程で難しかったことを書いていこうと思います。
Reactでobnizのnpmパッケージを使うのができなかった。
今回はobnizというマイコンを使って開発を行ったのですが、このobnizをReactで使うことに苦戦しました。obniz用のnpmパッケージがあるのでそれを使いたかったのですが、謎のエラーで動かず苦戦しました。
実はこのことをFacebookで呟くと@wicketさんにその解決方法の記事を書いてくださいました。なのですが、今回はライブラリを使わずに直接Websoketを使ってobnizとのやりとりを実装しました(ごめんなさい。。)。
const connectSensor = () => {
const socket = new WebSocket(host + `/obniz/${sensorId}/ws/1`)
socket.onmessage = (event) => {
const arr = JSON.parse(event.data)
for (let i = 0; i < arr.length; i++) {
const obj = arr[i]
if (obj.ws && obj.ws.redirect) {
socket.onmessage = null
socket.close()
setHost(obj.ws.redirect)
connectSensor()
}
if (obj.ws && obj.ws.ready) {
setSensorId('')
setConnectable(false)
socket.send(JSON.stringify([
{
io0: {
direction: "output",
value: true
},
},
{
ad1: {
stream: true
}
},
{
io2: {
direction: "output",
value: false
},
},
]))
}
if (obj.ad1) {
setData(Number(obj.ad1))
}
}
}
}
これでもコード量は大したことはないのですが、やっぱりライブラリを使ったほうが実装はキレイになるので積極的に使っていきたいところではあります。。。
ニオイの検出はさすがに難しい
これはもともと難しいと思っていたので真面目に取り組むつもりはなかったのですが(こういうサボりぐせが良くないんだろうなとも思ってますが)、センサーから安定した値を入力させること自体も結構難しかったです。今回実装した処理は
if (data > 0.2) {
setGalic(galic + 1)
}
ぐらいのあまりにもひどすぎる実装なのですが、これでも難しかった(というよりは面倒だった)のは今回用いたガスセンサの値が安定しなさすぎることでした。これはニオイセンサではなく本来の用途はガス漏れなどの検知などに使うようなものみたいなので、吐いた息からニンニク臭をはかるという特殊な用途には向いてなかったのだろうなと思います(そらそうやで)。
ニンニク値のリアルタイム同期が難しい
今回SkyWayを使ってビデオチャットを実装しています(実装方法は自分の記事を参照した)。そしてSORAJIROに加えたい要素としてセンサー値をお互いにリアルタイムで同期させることをやりたかったのですが、良い実装方法がわからず結局センサー値を相手に送るボタンをつくって妥協する形になりました。データの送信にはSkyWayのsendメソッドを用いました。
export const SkyWay = ({ galic, setCalled }) => {
const conn = useRef(null)
...
const makeCall = () => {
const mediaConnection = peer.call(callId, localVideo.current.srcObject)
conn.current = peer.connect(callId)
mediaConnection.on('stream', async stream => {
remoteVideo.current.srcObject = stream
await remoteVideo.current.play().catch(console.error)
setCallId('')
setGalicable(true)
})
}
return (
...
<Button disabled={!galicable}
onClick={() => conn.current.send(galic)} color="primary">🧄ニンニクを投げる🧄</Button>
...
)
}
おわりに
まあ改めて記事でまとめてみると結局色々と課題は残っているのだなと思いました。おそらく来年もヒーローズリーグには挑戦するかとは思いますが、SORAJIROには飽きてしまったので別の作品でトライする可能性が高い気がしますが、やっぱり課題があるからこそモノづくりって楽しいなと思います。