« 部屋が薄暗くなると”GetWild”が流れ出す!?アプリ | トップページ | 3Dプリンタでパーツを強化できる教育分野向けロボット”XYZrobot Bolide” »

2016年4月 2日 (土)

Raspberry Pi 4足歩行ロボットのスタンドアロン化&ブラウザ操作

いつまでも外部電源に頼ってばかりじゃあ、ロボットとはいえません。

Img_1431

そういえば我が家にはこんなバッテリーがあることを思い出しまして。

これをRaspberry Pi Zero用電源にすることに。

サーボ用は先の円筒形のモバイルバッテリーをそのまま使います。

Img_0491

なるべく低重心にしたかったので、この通り底面にゴムで固定。

Img_0492

サーボ用バッテリーはご覧の通り隙間に突っ込んでテープで固定。

丸いので、どうにもいい固定方法が思いつきません・・・

バッテリー環境はこれでどうにか解決。

操作用インターフェースですが、結局ブラウザ操作することにしました。

ということで、Raspberry Pi大和でもお世話になった”Webiopi”の登場です。

以前書いた記事を参考にしましたが、

Raspberry Piに”WebIOPi”入れてみた: EeePCの軌跡

Raspberry Piでサーボと距離計、LED(SOS信号)をiPadのブラウザで操作できるようにしてみた: EeePCの軌跡

Webiopi自体がその後アップデートされているため、最新版を落として使うことに。

WebIOPi - The Raspberry Pi Internet of Things Framework

ここの”Download”から最新版をダウンロードし、Raspberry PiにログインしたTera Termにドラッグ&ドロップして転送しました。

現時点では0.7.1が最新版。ということで、

tar xvzf WebIOPi-0.7.1.tar.gz

と入力して解凍。

ディレクトリが生成されるので、

cd WebIOPi-0.7.1

と打ってディレクトリ移動、その中のsetup.shを実行します。

./setup.sh

以前はかなり時間がかかったような記憶ですが、そこはスペックアップしたRaspberry Pi Zero。思ったより短く終了。

ただ、途中で

Do you want to access WebIOPi over Internet ? [y/n]

などと聞かれますが、外からWebiopiを使うつもりでなければ”n”でOK。

インストールが終わると、

sudo /etc/init.d/webiopi start

と入力すればWebiopiが手動実行される・・・はずですが、動作しません。

しかし

sudo update-rc.d webiopi defaults

と入力し再起動をかけると、ちゃんと動作してくれます、Webiopi。変なの。

なんとか動作したので、あとはHTMLとWebiopi用Pythonコードを作成します。

■ test.html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title></title>
<script type="text/javascript" src="/webiopi.js"></script>
<script type="text/javascript">
webiopi().ready( function()
{
                var content, button;
                content = $("#content");

var content1, button1;
content1 = $("#content1");

button1 = webiopi().createMacroButton("Forward", "Forward", "Servo0_H_Min");
content1.append(button1);

button1 = webiopi().createMacroButton("Backward", "Backward", "Servo0_H_Max");
content1.append(button1);

button1 = webiopi().createMacroButton("Left turn", "Left turn", "Servo0_H_Mid");
content1.append(button1);

button1 = webiopi().createMacroButton("Zero position", "Zero position", "Servo1_H_Max");
content1.append(button1);

button1 = webiopi().createMacroButton("Right turn", "Right turn", "Servo1_H_Min");
content1.append(button1);

} );

        function mousedown() {
                webiopi().setValue(25, 1);
        }

        function mouseup() {
                webiopi().setValue(25, 0);
        }

        function sequenceCallback(gpio, data) {
                alert("sequence on " + gpio + " finished with " + data);
        }

</script>
        <style type="text/css">
                button {
                        display: block;
                        margin: 5px 5px 5px 5px;
                        width: 160px;
                        height: 45px;
                        font-size: 14pt;
                        font-weight: bold;
                        color: black;
                }

                input[type="range"] {
                        display: block;
                        width: 160px;
                        height: 45px;
                }

                #gpio25.LOW {
                        background-color: White;
                }

                #gpio25.HIGH {
                        background-color: Red;
                }
        </style>
</head>
<body>
<table id="table">
<tr>
       <th> <div id="content" align="center"></div></th>
       <th> <div id="content1" align="center"></div></th>
</tr>
</table>
</body>
</html>


■ test.py

import webiopi
from webiopi import deviceInstance

webiopi.setDebug()

GPIO = webiopi.GPIO
pwm0 = deviceInstance("pwm0")

def setup():
        GPIO.setFunction( 25, GPIO.OUT )
        GPIO.output(25, GPIO.HIGH)

def loop():
    GPIO.output(25, not GPIO.input(25))
    webiopi.sleep(5)

@webiopi.macro
def Servo0_H_Min():
    servo0_h_min()

def servo0_h_min():
  for i in range(0,3):
    pwm0.pwmWriteAngle(0,-22) 
    pwm0.pwmWriteAngle(1, 22) 
    pwm0.pwmWriteAngle(2, 0) 
    pwm0.pwmWriteAngle(3, 0) 
    pwm0.pwmWriteAngle(4, 0)
    pwm0.pwmWriteAngle(5, 0)
    pwm0.pwmWriteAngle(6, 30)
    pwm0.pwmWriteAngle(7,-22)
    webiopi.sleep(0.1)
    pwm0.pwmWriteAngle(0,   0) 
    pwm0.pwmWriteAngle(1,  22) 
    pwm0.pwmWriteAngle(2,   0) 
    pwm0.pwmWriteAngle(3,   0) 
    pwm0.pwmWriteAngle(4,   0)
    pwm0.pwmWriteAngle(5,   0)
    pwm0.pwmWriteAngle(6,   0)
    pwm0.pwmWriteAngle(7, -22)
    webiopi.sleep(0.1)
    pwm0.pwmWriteAngle(0,   0) 
    pwm0.pwmWriteAngle(1,   0) 
    pwm0.pwmWriteAngle(2,  22) 
    pwm0.pwmWriteAngle(3,   0) 
    pwm0.pwmWriteAngle(4, -22)
    pwm0.pwmWriteAngle(5,   0)
    pwm0.pwmWriteAngle(6,   0)
    pwm0.pwmWriteAngle(7,   0)
    webiopi.sleep(0.1)
    pwm0.pwmWriteAngle(0,   0) 
    pwm0.pwmWriteAngle(1,   0) 
    pwm0.pwmWriteAngle(2,  22) 
    pwm0.pwmWriteAngle(3,  22) 
    pwm0.pwmWriteAngle(4, -22)
    pwm0.pwmWriteAngle(5, -22)
    pwm0.pwmWriteAngle(6,   0)
    pwm0.pwmWriteAngle(7,   0)
    webiopi.sleep(0.1)
    pwm0.pwmWriteAngle(0,   0) 
    pwm0.pwmWriteAngle(1,   0) 
    pwm0.pwmWriteAngle(2, -22) 
    pwm0.pwmWriteAngle(3,  22) 
    pwm0.pwmWriteAngle(4,  22)
    pwm0.pwmWriteAngle(5, -22)
    pwm0.pwmWriteAngle(6,   0)
    pwm0.pwmWriteAngle(7,   0)
    webiopi.sleep(0.1)
    pwm0.pwmWriteAngle(0,   0) 
    pwm0.pwmWriteAngle(1,   0) 
    pwm0.pwmWriteAngle(2, -22) 
    pwm0.pwmWriteAngle(3,   0) 
    pwm0.pwmWriteAngle(4,  22)
    pwm0.pwmWriteAngle(5,   0)
    pwm0.pwmWriteAngle(6,   0)
    pwm0.pwmWriteAngle(7,   0)
    webiopi.sleep(0.1)
    pwm0.pwmWriteAngle(0,   0) 
    pwm0.pwmWriteAngle(1, -22) 
    pwm0.pwmWriteAngle(2,   0) 
    pwm0.pwmWriteAngle(3,   0) 
    pwm0.pwmWriteAngle(4,   0)
    pwm0.pwmWriteAngle(5,   0)
    pwm0.pwmWriteAngle(6,   0)
    pwm0.pwmWriteAngle(7,  22)
    webiopi.sleep(0.1)
    pwm0.pwmWriteAngle(0, -22) 
    pwm0.pwmWriteAngle(1, -22) 
    pwm0.pwmWriteAngle(2,   0) 
    pwm0.pwmWriteAngle(3,   0) 
    pwm0.pwmWriteAngle(4,   0)
    pwm0.pwmWriteAngle(5,   0)
    pwm0.pwmWriteAngle(6,  30)
    pwm0.pwmWriteAngle(7,  22)
    webiopi.sleep(0.1)
    pwm0.pwmWriteAngle(0, -22) 
    pwm0.pwmWriteAngle(1,   0) 
    pwm0.pwmWriteAngle(2,   0) 
    pwm0.pwmWriteAngle(3,   0) 
    pwm0.pwmWriteAngle(4,   0)
    pwm0.pwmWriteAngle(5,   0)
    pwm0.pwmWriteAngle(6,  30)
    pwm0.pwmWriteAngle(7,   0)
    webiopi.sleep(0.1)
    pwm0.pwmWriteAngle(0,   0)
    pwm0.pwmWriteAngle(1,   0)
    pwm0.pwmWriteAngle(2,   0)
    pwm0.pwmWriteAngle(3,   0)
    pwm0.pwmWriteAngle(4,   0)
    pwm0.pwmWriteAngle(5,   0)
    pwm0.pwmWriteAngle(6,   0)
    pwm0.pwmWriteAngle(7,   0)
    webiopi.sleep(0.2)

@webiopi.macro
def Servo0_H_Max():
    servo0_h_max()

def servo0_h_max():
  for i in range(0,3):
    pwm0.pwmWriteAngle(0,  -22) 
    pwm0.pwmWriteAngle(1,  -22) 
    pwm0.pwmWriteAngle(2,   0) 
    pwm0.pwmWriteAngle(3,   0) 
    pwm0.pwmWriteAngle(4,   0)
    pwm0.pwmWriteAngle(5,   0)
    pwm0.pwmWriteAngle(6,  30)
    pwm0.pwmWriteAngle(7,  22)
    webiopi.sleep(0.1)
    pwm0.pwmWriteAngle(0,   0) 
    pwm0.pwmWriteAngle(1,  -22) 
    pwm0.pwmWriteAngle(2,   0) 
    pwm0.pwmWriteAngle(3,   0) 
    pwm0.pwmWriteAngle(4,   0)
    pwm0.pwmWriteAngle(5,   0)
    pwm0.pwmWriteAngle(6,   0)
    pwm0.pwmWriteAngle(7,  22)
    webiopi.sleep(0.1)
    pwm0.pwmWriteAngle(0,   0) 
    pwm0.pwmWriteAngle(1,   0) 
    pwm0.pwmWriteAngle(2,  -22) 
    pwm0.pwmWriteAngle(3,   0) 
    pwm0.pwmWriteAngle(4,  22)
    pwm0.pwmWriteAngle(5,   0)
    pwm0.pwmWriteAngle(6,   0)
    pwm0.pwmWriteAngle(7,   0)
    webiopi.sleep(0.1)
    pwm0.pwmWriteAngle(0,   0) 
    pwm0.pwmWriteAngle(1,   0) 
    pwm0.pwmWriteAngle(2,  -22) 
    pwm0.pwmWriteAngle(3,  22) 
    pwm0.pwmWriteAngle(4,  22)
    pwm0.pwmWriteAngle(5,  -22)
    pwm0.pwmWriteAngle(6,   0)
    pwm0.pwmWriteAngle(7,   0)
    webiopi.sleep(0.1)
    pwm0.pwmWriteAngle(0,   0) 
    pwm0.pwmWriteAngle(1,   0) 
    pwm0.pwmWriteAngle(2,  22) 
    pwm0.pwmWriteAngle(3,  22) 
    pwm0.pwmWriteAngle(4,  -22)
    pwm0.pwmWriteAngle(5,  -22)
    pwm0.pwmWriteAngle(6,   0)
    pwm0.pwmWriteAngle(7,   0)
    webiopi.sleep(0.1)
    pwm0.pwmWriteAngle(0,   0) 
    pwm0.pwmWriteAngle(1,   0) 
    pwm0.pwmWriteAngle(2,  22) 
    pwm0.pwmWriteAngle(3,   0) 
    pwm0.pwmWriteAngle(4,  -22)
    pwm0.pwmWriteAngle(5,   0)
    pwm0.pwmWriteAngle(6,   0)
    pwm0.pwmWriteAngle(7,   0)
    webiopi.sleep(0.1)
    pwm0.pwmWriteAngle(0,   0) 
    pwm0.pwmWriteAngle(1,  22) 
    pwm0.pwmWriteAngle(2,   0) 
    pwm0.pwmWriteAngle(3,   0) 
    pwm0.pwmWriteAngle(4,   0)
    pwm0.pwmWriteAngle(5,   0)
    pwm0.pwmWriteAngle(6,   0)
    pwm0.pwmWriteAngle(7,  -22)
    webiopi.sleep(0.1)
    pwm0.pwmWriteAngle(0,  -22) 
    pwm0.pwmWriteAngle(1,  22) 
    pwm0.pwmWriteAngle(2,   0) 
    pwm0.pwmWriteAngle(3,   0) 
    pwm0.pwmWriteAngle(4,   0)
    pwm0.pwmWriteAngle(5,   0)
    pwm0.pwmWriteAngle(6,  30)
    pwm0.pwmWriteAngle(7,  -22)
    webiopi.sleep(0.1)
    pwm0.pwmWriteAngle(0,  -22) 
    pwm0.pwmWriteAngle(1,   0) 
    pwm0.pwmWriteAngle(2,   0) 
    pwm0.pwmWriteAngle(3,   0) 
    pwm0.pwmWriteAngle(4,   0)
    pwm0.pwmWriteAngle(5,   0)
    pwm0.pwmWriteAngle(6,  30)
    pwm0.pwmWriteAngle(7,   0)
    webiopi.sleep(0.1)
    pwm0.pwmWriteAngle(0,   0)
    pwm0.pwmWriteAngle(1,   0)
    pwm0.pwmWriteAngle(2,   0)
    pwm0.pwmWriteAngle(3,   0)
    pwm0.pwmWriteAngle(4,   0)
    pwm0.pwmWriteAngle(5,   0)
    pwm0.pwmWriteAngle(6,   0)
    pwm0.pwmWriteAngle(7,   0)
    webiopi.sleep(0.2)

@webiopi.macro
def Servo0_H_Mid():
    servo0_h_mid()

def servo0_h_mid():
  for i in range(0,8):
    pwm0.pwmWriteAngle(0,  -22) 
    pwm0.pwmWriteAngle(1,  22) 
    pwm0.pwmWriteAngle(2,   0) 
    pwm0.pwmWriteAngle(3,   0) 
    pwm0.pwmWriteAngle(4,   0)
    pwm0.pwmWriteAngle(5,   0)
    pwm0.pwmWriteAngle(6,   0)
    pwm0.pwmWriteAngle(7,   0)
    webiopi.sleep(0.1)
    pwm0.pwmWriteAngle(0,   0) 
    pwm0.pwmWriteAngle(1,  22) 
    pwm0.pwmWriteAngle(2,   0) 
    pwm0.pwmWriteAngle(3,   0) 
    pwm0.pwmWriteAngle(4,   0)
    pwm0.pwmWriteAngle(5,   0)
    pwm0.pwmWriteAngle(6,   0)
    pwm0.pwmWriteAngle(7,   0)
    webiopi.sleep(0.1)
    pwm0.pwmWriteAngle(0,   0) 
    pwm0.pwmWriteAngle(1,   0) 
    pwm0.pwmWriteAngle(2,   0) 
    pwm0.pwmWriteAngle(3,   0) 
    pwm0.pwmWriteAngle(4,  -22)
    pwm0.pwmWriteAngle(5,   0)
    pwm0.pwmWriteAngle(6,   0)
    pwm0.pwmWriteAngle(7,   0)
    webiopi.sleep(0.1)
    pwm0.pwmWriteAngle(0,   0) 
    pwm0.pwmWriteAngle(1,   0) 
    pwm0.pwmWriteAngle(2,   0) 
    pwm0.pwmWriteAngle(3,   0) 
    pwm0.pwmWriteAngle(4,   0)
    pwm0.pwmWriteAngle(5,  -22)
    pwm0.pwmWriteAngle(6,   0)
    pwm0.pwmWriteAngle(7,   0)
    webiopi.sleep(0.1)
    pwm0.pwmWriteAngle(0,   0)
    pwm0.pwmWriteAngle(1,   0)
    pwm0.pwmWriteAngle(2,   0)
    pwm0.pwmWriteAngle(3,   0)
    pwm0.pwmWriteAngle(4,   0)
    pwm0.pwmWriteAngle(5,   0)
    pwm0.pwmWriteAngle(6,   0)
    pwm0.pwmWriteAngle(7,   0)
    webiopi.sleep(0.2)

@webiopi.macro
def Servo1_H_Min():
    servo1_h_min()

def servo1_h_min():
  for i in range(0,8):
    pwm0.pwmWriteAngle(0,   0) 
    pwm0.pwmWriteAngle(1,   0) 
    pwm0.pwmWriteAngle(2,  -22) 
    pwm0.pwmWriteAngle(3,  22) 
    pwm0.pwmWriteAngle(4,   0)
    pwm0.pwmWriteAngle(5,   0)
    pwm0.pwmWriteAngle(6,   0)
    pwm0.pwmWriteAngle(7,   0)
    webiopi.sleep(0.1)
    pwm0.pwmWriteAngle(0,   0) 
    pwm0.pwmWriteAngle(1,   0) 
    pwm0.pwmWriteAngle(2,  -22) 
    pwm0.pwmWriteAngle(3,   0) 
    pwm0.pwmWriteAngle(4,   0)
    pwm0.pwmWriteAngle(5,   0)
    pwm0.pwmWriteAngle(6,   0)
    pwm0.pwmWriteAngle(7,   0)
    webiopi.sleep(0.1)
    pwm0.pwmWriteAngle(0,   0) 
    pwm0.pwmWriteAngle(1,   0) 
    pwm0.pwmWriteAngle(2,   0) 
    pwm0.pwmWriteAngle(3,   0) 
    pwm0.pwmWriteAngle(4,   0)
    pwm0.pwmWriteAngle(5,   0)
    pwm0.pwmWriteAngle(6,   0)
    pwm0.pwmWriteAngle(7,  22)
    webiopi.sleep(0.1)
    pwm0.pwmWriteAngle(0,   0) 
    pwm0.pwmWriteAngle(1,   0) 
    pwm0.pwmWriteAngle(2,   0) 
    pwm0.pwmWriteAngle(3,   0) 
    pwm0.pwmWriteAngle(4,   0)
    pwm0.pwmWriteAngle(5,   0)
    pwm0.pwmWriteAngle(6,  22)
    pwm0.pwmWriteAngle(7,   0)
    webiopi.sleep(0.1)
    pwm0.pwmWriteAngle(0,   0)
    pwm0.pwmWriteAngle(1,   0)
    pwm0.pwmWriteAngle(2,   0)
    pwm0.pwmWriteAngle(3,   0)
    pwm0.pwmWriteAngle(4,   0)
    pwm0.pwmWriteAngle(5,   0)
    pwm0.pwmWriteAngle(6,   0)
    pwm0.pwmWriteAngle(7,   0)
    webiopi.sleep(0.2)

@webiopi.macro
def Servo1_H_Max():
    servo1_h_max()

def servo1_h_max():
    pwm0.pwmWriteAngle(0,   0)
    pwm0.pwmWriteAngle(1,   0)
    pwm0.pwmWriteAngle(2,   0)
    pwm0.pwmWriteAngle(3,   0)
    pwm0.pwmWriteAngle(4,   0)
    pwm0.pwmWriteAngle(5,   0)
    pwm0.pwmWriteAngle(6,   0)
    pwm0.pwmWriteAngle(7,   0)
    webiopi.sleep(0.2)

当然ですが、”test.py”の記述はコマンドライン用のコードとは若干違います。test.html、test.pyともに大和のときに使ったやつを流用してます。

サーボ制御のコマンドは、例えば「pwm.setPWM(1, 0, 450)」なら「pwm0.pwmWriteAngle(1,22)」のようになります。こちらでは角度指定(-90度~90度)のため、記述が変わります。

これをホームディレクトリ(/home/pi)の下にwebiopiというディレクトリを作っておき、この2つのコードを入れます。

このままでは動かないので、Webiopiのconfigファイルをいじります。

sudo vi /etc/webiopi/config

まず25行目付近の[SCRIPTS]に一行加えます。

myscript = /home/pi/webiopi/test.py

続いて、[HTTP]にある36行目の「passwd-file =」の行を#でコメントアウトしておきます。

#passwd-file = /etc/webiopi/passwd

これでいちいちブラウザでアクセスするたびにIDとパスワードの入力手間が省けます。

同じ[HTTP]の39行目「doc-root =」を以下のように変えます。

doc-root = /home/pi/webiopi

その3行下の「welcome-file =」も変更

welcome-file = test.html

最後に[DEVICES]の項目にある91行目にある以下の行のコメントアウトをはずします。

pwm0 = PCA9685

これを有効にしておかないと、PCA9685がWebiopiで動作してくれません。

ここまで下準備をしてようやく動きます。

Img_1444

わかりにくいですが、「前進」「後退」「左」「右」「ゼロ点」の5つのボタン配置が適当になってます。とりあえず動作確認用ってことで。

いざ!スタンドアロン歩行!!

Img_1446

一応動作するんですが、明らかに重すぎな動作をします。とくに後ろ側。

Img_1447

とくに左後ろ足の負担が大きいらしく、この通りぼろぼろ取れます。

工作精度も低いため、出来た脚の配置も左後ろ足に負担をかけるような形になってるようです。

Img_1448

なるべく重心を前へ動かそうとするんですが、せいぜいこのバッテリーがこの程度しか動きません。

サーボ用のバッテリー、もっと軽いのを探すしかないのか・・・

なおサーボ用に使ってるこのバッテリー、サーボを動かさないと30秒ほどで電源カット。そのたびにスイッチオン。なんともせっかちなバッテリーです。

左足のサーボホーンのみ、アロンアルファで引っ付けておきました。

今回のロボット製作、アロンアルファの出番が多すぎです。

一応、子供と遊べる程度のロボットは完成。

Img_0493

ところでこのロボット、何か名前をつけてやろうかと思ったんですが。

この姿、どこかで見たことがある・・・

そうだNHKスペシャル「地球大進化」に出てきた「爬虫類型哺乳類」にそっくり!

reserch of mamal-like reptiles tour in South Afrika '94_1

ググると「リストロサウルス」というのがわりとそっくりだと判明。

ということで、「リストロ」と名づけてみました。

会社が経営難に陥った時にやるアレみたいな名前ですが・・・もうちょっと考えようかな。

さらに欲を出して、Webカメラつけたり物を運ばせたりさせようかと思ったんですが・・・

「もうやめて!リストロの積載残量はもう0よ!!」

てことであきらめることに。

やはりバッテリーの重さが想定外でしたねぇ・・・一つのバッテリーでなんとかいけると思ったんですが、ある一定容量以下のモバイルバッテリーは1Aしか出ないことを考慮してませんでした。

サーボ用のバッテリーを低容量のものにすれば今でも軽量化できるんでしょうが、ちょっと今回はお金使いすぎちゃいました。

今度ロボットを作ることがあったら、バッテリーの選択から考えて作ることにします。

さて、ここまで出来たので、子供と遊んでみたんですが。

Img_1473

20分ほど遊んでたら、今度は足裏のクッションがはがれました。

しかもサーボが時々おかしな動きになるし、あまり安定した動きとはいいがたかったんですが。

しかし、子供には大うけでした。

そりゃ目の前でぼろぼろ壊れたり時々暴走気味になるロボットなんて、めったにお目にかかれるものではありませんから。

ロボットとしては失格ですが、子供相手には最高のロボットになれたようです。

が、ここまで作っておいていうのもなんですが、ロボット作るならArduinoの方が向いてますね、多分。

Linuxで動かしているため、なんというか無理やり感があります。

その代わり、自身のなれた言語(PythonでもCでもScratch・・・さすがにFortranは無理か!?)でシステムが組めるので、柔軟性はRaspberry Piの方が上です。

手軽にロボット作りが出来るというのが、Raspberry Piの売りじゃないでしょうか?

今までの製作記を最後にまとめておきます。

Raspberry Piで4足歩行ロボット作ってみた: EeePCの軌跡

自作Raspberry Pi4足歩行ロボットでRaspberry Pi Zeroに換装: EeePCの軌跡

Raspberry Pi3 Model B (Element14)

« 部屋が薄暗くなると”GetWild”が流れ出す!?アプリ | トップページ | 3Dプリンタでパーツを強化できる教育分野向けロボット”XYZrobot Bolide” »

ロボット系」カテゴリの記事

おもちゃ系」カテゴリの記事

Raspberry Pi・Arduino・電子工作」カテゴリの記事

コメント

そうなってくると市販品の
パチモンだと言われるような
ロボットも一応動いたりするのは
とても凄いことだと思えますね

こんにちは、mokekyoさん。

行き当たりばったりで良くここまで作れたものだと思いますが、やはり市販品のロボットは重心や剛性など考えられているものが多いと感じます。

ただ強度まで大丈夫かと心配になるものもあるのは事実ですが、人のことは言えませんね。

コメントを書く

(ウェブ上には掲載しません)

トラックバック


この記事へのトラックバック一覧です: Raspberry Pi 4足歩行ロボットのスタンドアロン化&ブラウザ操作:

« 部屋が薄暗くなると”GetWild”が流れ出す!?アプリ | トップページ | 3Dプリンタでパーツを強化できる教育分野向けロボット”XYZrobot Bolide” »

無料ブログはココログ

スポンサード リンク

ブログ村