はじめに
ペットカメラを作ったけど、フレームにペットが映ってない!
カメラを動かしたい!
「カメラ、あとちょっと左向いて!」
ということがありました。
そう思ったら、カメラを動くようにするのがエンジニアです。
このような構成になります。
なお、この記事は以下の記事で開発したソフトをベースにしていますので、見ていない方はこちらを先に見ていただくとわかりやすいかと思います。
この記事では以下のような流れで説明していきます。
- 全体像
- Raspberry Piの配線
- SkyWayとの通信
- pet-cam-piの説明
- 実行方法
1. 全体像
デバイスやスマホ、クラウドは、下の図のように通信します。
自宅側
自宅側には、Raspberry Piとサーボがあります。
Raspberry Piでは、node.jsプログラムとしてpet-cam-piサーバーが動いています。
このpet-cam-piサーバーはhttpサーバーになっており、Raspberry Pi内部のブラウザにペットカメラのWebページを公開します。また、RESTサーバーとして、サーボ操作APIを提供します。
SkyWayからサーボ角度がブラウザに届くので、ブラウザのjavascriptはサーボ角度を受け取ったら、pet-cam-piにRESTでPOSTしてサーボ角度を設定します。
# サーボ操作APIをcurlから行う例、angleはdegreeではなく、サーボ上の角度設定範囲の0%~100%を意味する
curl -X POST -H 'Content-Type: application/json' -d '{"angle":10}' http://localhost:8080/servo
外出先
外出先では、スマホからGitHub Pagesのペットカメラ用のWebサイトを開きます。
スマホでは、SkyWayから送信される動画/音声を表示します。
SkyWay経由でサーボ角度をRaspberry Piのブラウザに配信します。
2. Raspberry Piの配線
Raspberry Piとサーボモーターは以下のように配線します。
Piの電源で動く小さめのサーボを使いましょう。
Pi 2pin (5V Power) -> Servo VCC
Pi 6pin (Ground) -> Servo GND
Pi 12pin (GPIO 18) -> Servo SIGNAL
Raspberry PiからはGPIOを使って、サーボのDuty比を操作することで、サーボモーターの上に乗っているUSBカメラの角度を制御します。
3. SkyWayとの通信
前記事のインターネットペットカメラでは、Streamとして
- VideoStream (ビデオ映像)
- AudioStream (オーディオ音声、マイク音声)
のみを使っていましたが、今回はサーボ角度の送信のために
- DataStream (任意のメッセージ、P2P Roomでのみ使える)
を追加で使います。
Dataの送信
Dataを送信するためには、まず以下のようにDataStreamを準備します。
const me = await channel.join();
const data = await SkyWayStreamFactory.createDataStream();
await me.publish(data);
実際に送信するには
data.write(JSON.stringify({angle: servoAngle}));
のようにすることでデータを送ることができます。
Dataの受信
Dataを受信するためには、以下のようにSubscribeします。
const subscribeAndAttach = async (publication) => {
if (publication.publisher.id === me.id) return;
const { stream } = await me.subscribe(publication.id);
switch (stream.contentType) {
case 'data':
{
stream.onData.add(async (data) => {
const obj = JSON.parse(data as string);
const angle:number = obj.angle;
console.log('angle:' + angle);
});
}
break;
}
};
channel.publications.forEach(subscribeAndAttach);
channel.onStreamPublished.add((e) => subscribeAndAttach(e.publication));
SkyWayのJavaScript SDKを使って、簡単にメッセージ送受信機能を実装することができます。
4. pet-cam-piの説明
pet-cam-piではhttpサーバーとしてexpressを利用しています。
expressでは以下の処理で、publicフォルダのペットカメラWebコンテンツを公開できます。
app.use('/', express.static('public'));
そして、サーボ角度が/servo
にPOSTされたら、以下のようにサーボ角度を設定します。
app.post('/servo', async (req, res) => {
let anglePercentage:number = req.body.angle;
if (anglePercentage === undefined) {
res.status(400).send('angle is undefined');
return;
}
currentAngle = Math.max(0, Math.min(100, anglePercentage));
setServoAngleByPercentage(currentAngle);
res.status(200).send('ok');
});
実際のサーボ操作は、pigpioを使っており、以下のような感じになっています。
import {Gpio} from 'pigpio';
const motor = new Gpio(18, {mode: Gpio.OUTPUT});
const PulseWidthMax = 2500;
const PulseWidthMin = 500;
const setServoAngleByPercentage = (anglePercentage:number) => {
const pulseWidth = ~~(PulseWidthMin + (PulseWidthMax - PulseWidthMin) * anglePercentage / 100);
console.log('set servo angle: ' + anglePercentage + ' pulse width: ' + pulseWidth);
motor.servoWrite(pulseWidth);
};
ここでPulseWidthMax
やPulseWidthMin
は利用しているサーボのパルス幅で、サーボごとに変更してください。私が使ったサーボの場合はパルス幅0.5ms-2.5msの範囲で、サーボ角度0°-270°の制御ができます。
5. 実行方法
pet-cam-piのリポジトリを公開しています。
Raspberry piにログインして、
# clone pet-cam repository from GitHub
% git clone https://github.com/komasayuki/pet-cam-pi
% cd pet-cam-pi/server
# first time only
% npm install
# pet-cam-piサーバーを起動、8080ポートで待ち受け
% sudo npm start
これでpet-cam-piサーバーが起動できました。
自宅カメラ側の起動
Raspberry Piのpet-cam-piが起動している状態で、ブラウザで
カメラ用URL
を開いて、SkyWayで取得した、あなたのアプリケーションID
とシークレットキー
を入力します。
(まだ取得していなければ、SkyWayのサイトから無料で作れます)
これで自宅カメラ側の準備が完了です。
外出先でペットカメラを見る
外出先のスマホからは
ビューワー用URL
を開いて、あなたのアプリケーションID
とシークレットキー
を入力してください。
あなたの大好きなペットは映りましたか?
サーボの角度も変えてみましょう!
最後に
SkyWayのJavaScript SDKは、とても良くできていて、前記事のインターネットペットカメラから、簡単にサーボ操作機能を追加することができました。
双方向通信が可能になるDateStreamは様々な用途に使えそうですね。