« 週刊myRobotちょっとひといき(5) | トップページ | 週刊myRobotちょっとひといき(6) »

2008年1月19日 (土)

週刊myRobotを作ろう(86)

■更新情報 テレビリモコンブログラム (2008/1/20)

今年初めてのmyRobotの記事になります。
本年もどうぞ宜しくお願いします。

■ブレインOSのアップデート
イタリアデアゴ社のWebサイトにブレインOSのアップデートが2007/12/14付けでUPされています。
とりあえず、ZIPファイルをダウンロードして解凍し、ID-01のブレインOSをアップデートしてみました。Id01_91_23
”BRN-15JP”から”BRN-16JP”になった

ID-01の胸のディスプレイには、ご覧のように”BRN-16JP”と表示されています。
いろいろ動作テストをしてみましたが、特に問題は無い様です。

「週刊myRobt」が90号で完了してしまったこれからは、CD-ROM5などは来る術も無く、このような形でアップデートするしか方法が無いのでしょうか・・・・
Version1.6をダウンロードするには、ここをクリックすれば可能ですが、インストール時に出るDOSプロンプトのインフォメーションは、(当然ながら)イタリア語です。
日本のデアゴさんからは何の通達が出ていませんので、先行してダウンロード及びインストールされる方は自己責任でお願いします。
尚、問題があるようでしたら、CD-ROM4の”BRN-15JP”には再インストールすれば戻る事が可能です。
    
■プログラムを改良する・・・
以前から気になっていたのですが、VCL(Visual C-like)で組んだプログラムでは、左右の旋回が片車輪停止、反対側の車輪が動く、いわゆる急旋回としてしか組むことができません。
前進運動中に軽く進行方向を修正させ、そのまま直進させたい時など、急旋回は興ざめです。

◇穏旋回
これに対し、両車輪が回転しながらも、片方の車輪が反対側より遅くなる事により、穏やかな旋回(以後、穏旋回といいます)を行うには、PC_Control、Mobile_Control、C-Cでは可能なものの、VCLEではプログラミングが不可能でした。
従って、従来のVCLEで作成したユニリモコンのプログラムでは、なにかぎこちない旋回しか出来ずに不満に思っていました。
C-Like周りの資料を調べていたところ、”I2Cプロトコル”で穏旋回が出来る事が分りました。
”I2Cプロトコル”の解説を読むと、「I2Cバス上のモジュール間の通信は、それぞれのモジュールが使用可能なバーチャル・レジストリの書き込み/読み込みによって行われる。」と記載されており、沢山のコマンド群が記載されています。
早速、これにとりかかろうと思った矢先、年末から体調を崩しダウンしてしまいました。Id01_91_22
    
◇フルスピード
先日、KENさんから「遂にT-Droidなみの88回転/分を実現しました!」とのメールが届きました。
内容は、C-Likeで”I2Cプロトコル”を用いたBASE制御により、「PIDコントロールなしのパラメーターによる移動」でスピードが100%出る・・・という内容で、数行のプログラムが添付されていました。
このプログラム及び記事については、KENさんのブログにある「遂に実現!ロボ君フルスピード!」をご覧ください。

ID-01が移動する場合、通常はPIDコントロール(エンコーダーによるパルス制御)により、左右の回転がシンクロするように制御されております。この場合、最速でも100%の速度を出すことは出来ません。
KENさんのブログによりますと、車輪の回転でMAX88回転/分に対し、PIDコントロール有りの現在の回転数は実に49回転/分だそうです。ID-01の走行スピードに不満を持たれている方が多いのは、このせいです。

一方、このPIDコントロールを無くする事により100%のスピードが実現します。
この100%のスピードが「T-Droidなみの88回転/分」という事になります。
良い事づくめのようですが、左右の回転が制御されていない事から、左右の回転数の同調がとれず、個々のモーターボックス特性の僅かな差異から、直進する事が難しくなります。

◇I2Cプロトコル
KENさんに紹介していただいた、この突っ走りモードのコア部分を分析してみると、”I2Cプロトコル”でした。
これで年末に成し得なかった、同じI2Cプロトコル”で動作する「穏旋回」が、難なく可能になった事になります。

早速、テレビリモコンのプログラムに、「穏旋回」と、KENさんの「突っ走り」の機能を組み込み、テストを開始しました。
「Boost(突っ走り)」モードにすると、僅かながら左に曲がっていきます。
おそらく、左右のモーターボックスの僅かな特性の違いなのでしょう・・・・
全く同じ回転にするのは、かなり難しいかもしれませんね。

◇CL(C-Like)によるプログラミング
”I2Cプロトコル”はCL上でしか動作しませんので、今回はCLでプログラミングしてあります。
本来は、分かりやすいVCLでのプログラムで解説しながら・・・と思ったのですが、今回不可能ですので、ご了承ください。

■テレビリモコンの改良
従来のテレビリモコンプログラムでは、リモコンによる物を掴むとき用に微調整可能な、左右旋回はアングル指定45度、15度旋回を行えるようにしてありますので、この機能は残す事にしました。
併せて、「Boost(突っ走り)」モードを加えます。
今回は、「多機能リモコン」以外に、「一般のテレビリモコン(1~12)」でも使える機能限定版の2つのプログラムを用意する事にしました。

◇旋回モード
●穏旋回
穏旋回させるには、「走行ボタン」を押して前進させてから「左(右)旋回ボタン」を押すと、緩やかに旋回します。
穏旋回中、さらに同方向の旋回ボタンを押す事により急旋回(方車輪が止まった状態)に移るようにしてあります。
「前進」→「左(右)旋回」(穏旋回)→「左(右)旋回」(急旋回)という感じです。
そのままにしていますと、何時までも旋回を続けますので、「前進」あるいは「停止」ボタンを押して抜け出す事が出来ます。

●アングル指定旋回

尚、従来のアングル指定の旋回は、「停止」「後退」状態から入る事により可能です。
「停止」→「左(右)旋回」、「後退」→「左(右)旋回」

◇Boost(突っ走り)モード
KENさんが解説している「PIDコントロール無しの100%走行」モードです。
ID-01にしては、かなり速いな・・・・という位のスピードが出ます。
ただしスピードが楽しめる反面、バッテリーの減りには気をつける必要があります。
私は屋上で動作・走行テストをしていますが、Mobile ControlでB.T接続して、モバイルフォンのモニター画面で電圧をチェックしながら走行させています。
この走行モードですと、瞬間的に電圧がかなり低下しますので、このBoostパワーは、ここぞ・・という時に使用された方が良いと思います。

◇テレビリモコンの割り当て
先ほどもふれましたが、今回「多機能リモコン」と「普通のテレビリモコン」の2通りのプログラムをダウンロードできるようにしました。

重複しますが、以前「週刊myRobotを作ろう(84)」でご紹介した記事を使用して、まず「多機能リモコン」のコントロールの割り当てを説明します。
Id01_90_22
  
●多機能リモコン
前回とほとんど同仕様ですが、16に「Boost(突っ走り)モード」を追加しました。
①電源ボタン
プログラム終了
②ヘッドに関するセクション
各種警報、首の左右上下、中立、写真撮影、指の開閉
③ロボットの移動と手動きセクション
前後左右、Uターン、左右腕上下、腰上げ下げ
④音声の録音などに使用予定
多機能リモコンのプログラム概要は、こんなところです。

○詳細(赤字はユニリモコン割り当て番号)
①電源ボタン 0 
電源)プログラム終了
②セクション
1)クラクションと足のビーコン点灯 
2)サイレンと赤LED点滅 
3)口笛と緑LED点滅 
4)首左回転 
5)センター位置(左右動作) 5
6)首右回転 
7)上を向く 
8)センター位置(上下動作) 8 
9)下を向く 
10)手の開閉(トグル動作) 10
(トクル動作とは、一回押すたびに「開」または「閉」を、順番に繰り返します)
11)空き 11
12)写真撮影(赤LED点滅、目点滅、シャッター音) 12
③移動セクション
左側 +)左腕上へ 26
    -)左腕下へ 27

真ん中の4つのスイッチ
 上側) 緑LED点灯(トグル動作) 13
 2番目) 黄LED点灯(トグル動作) 14
 3番目) デジタル出力4(トグル動作) 15
 4番目) Boost(突っ走り)モード 16

右側 +)右腕上へ 28
    -)左腕下へ 29 

左列2ボタン
上側)左旋回15度 17
下側)180度ターン 18

クロスバータイプ
真ん中セレクトスイッチ
上)前進 21
左)左旋回(穏旋回と45度) 22
センタボタン)停止 25
右)右旋回(穏旋回と45度) 23
下)後進 24

右列2ボタン
上側)右旋回15度 19
下側)腰上げ下げ(トグル動作) 20
④音声録音セクション
未定義 30

●一般テレビリモコン

一般テレビリモコンでは、操作ボタンが少ない事から、多機能リモコンの機能を抜粋してアサインしました。Id01_90_22a
  
使用するのは、①電源スイッチと、②のチャンネル(1~12)ボタンだけです。
画像のように、「前(5)」「後(11)」「左(7)」「右(9)」と十字型を想定、真ん中の8で停止のように配列しました。
そして、「前進(5)」の真上に「Boost(2)」をアサインしました。

○詳細(赤字はユニリモコン割り当て番号)
①電源ボタン 0 
電源)プログラム終了

②チャンネルボタン
1)写真撮影(赤LED点滅、目点滅、シャッター音) 1
2)Boost(突っ走り)モード 
3)サイレンと赤LED点滅 
4)左旋回15度 
5)前進 
6)右旋回15度 
7)左旋回(穏旋回/45度) 
8)停止 
9)右旋回(穏旋回/45度) 
10)手の開閉(トグル動作) 10
(トクル動作とは、一回押すたびに「開」または「閉」を、順番に繰り返します)
11)後進 11
12)180度ターン 12

とりあえず主要な機能はモーラしています。

●PC_Controlによる登録方法
「多機能リモコン」と「一般のテレビリモコン」どちらの登録も、PC_Controlによる登録方法で行うと簡単に行えます。
週刊myRobotを作ろう(84)」の同項目名で詳細が載っておりますので、宜しければご参考にされて頂ければ・・・と思います。

◇「多機能リモコン」用、「一般テレビリモコン」用のプログラム公開
今回は2つのプログラムを公開します。
どちらもC-Likeで組みました。
「多機能リモコン」用は20以上の割付、「一般テレビリモコン」用は13の割付を行う事により、ID-01を自由にコントロールする事が可能です。

どちらのプログラムにも、前回同様、「プログラムロック防止の対応」として、リモコンのボタンを押した後、0.8秒間は次の命令を受け付けないようにポーズが掛かるようにしてあります。ただし、この対処はあくまでもプログラムロックが起こりにくくなるという対処ですので、完璧ではありません。どうぞご了承ください。

プログラムは、「ファイルのダンロード形式」と、その後に「ソースリスト形式」の2つの方式で公開しております。
お好きな方法で取り込んで頂き、参考頂ければ・・・と思っております。

(ご注意)
プログラムをダウンロードしてお使い頂くのはご自由ですが、あくまでも自己責任でご使用ください。

下の行からプログラムをダウンロードします。そして拡張子clikeで適当なフォルダーに保存して、VCLEで開いてください。
私は、”Remot_Control03Ux.clike”という名前で保存しました。
(03Uの後ろのxは、バージョンが更新されるたびに変わるので仮名をつけました)
プログラムをダウンロードされるときは、下の「ダウンロードでのご注意」をご覧ください。

*****************************************
{多機能リモコン用プログラムダウンロード}
「Remot_Control03Ub.clike」をダウンロード 

*****************************************

現在”Remot Control03Ub.clike”が最新バージョンです (2008/01/20)

*****************************************
{一般リモコン用プログラムダウンロード}
「Remot_Control01e.clike」をダウンロード 

*****************************************

現在”Remot Control01e.clike”が最新バージョンです (2008/01/20)

「ダウンロードでのご注意」
ファイルのダンロードに関しては、拡張子が”xml”に変わってしまいますので、お手数ですが、以下の方法でダンロードされてください。

1)上記ダウンロー
「Remot_Control03x.clike」をダウンロード を右クリックし、「対象をファイルに保存」を選択します。Id01_90_11
    
2)フィル名が、”RemotControl03x.xml”と出てきますので、後ろ3文字"xml"を消して、”clike”という文字を半角英字で入力して、任意のフォルダーに保存します。Id01_90_12_2

①"xml"3文字を、”clike”に変えて、②保存する
(画像クリックで拡大します)

■テレビリモコンプログラム
プログラムは「掲示板」で良く使われているプログラムソース形式です。

ソース形式のプログラムは、カット&ペーストで、テキストエディターに読み込み、適当な名前で保存してC Editorで読み込んでご利用下さい。

◇多機能リモコン用
ここから下です------------------------------
/**
*
* @author fumi
* @version 1.0
*/

#include "c-like.h"
#include "robot.h"

counter Flag1 = new(counter);
counter FlagD1 = new(counter);
counter FlagD2 = new(counter);
counter FlagD3 = new(counter);
counter FlagHand = new(counter);
counter FlagHip = new(counter);
counter FlagD4 = new(counter);
counter FlagFine = new(counter);
counter FlagLR = new(counter);

declare( behavior(Action) );

void Forward();
void Back();
void Stop();
void Right();
void Left();
void Init();
void Fine();
void Right15();
void Left15();
void Turn();
void HomePos();
void TakePic();
void Boost();

define( behavior(Main))
{
Init();
start(Action);
}

define( behavior(Action) )
{
local(urc) = wait_for (urc, update);
if (urc_compare(&local(urc), 0))
{
  say_phrase(4);
  Fine();
  say_phrase(22);
  stop(Action);
}
else
{
}
if (urc_compare(&local(urc), 21))
{
  say_phrase(27);
  Forward();
}
else
{
  if (urc_compare(&local(urc), 22))
  {
   say_phrase(23);
   Left();
  }
  else
  {
   if (urc_compare(&local(urc), 25))
   {
    say_phrase(4);
    Stop();
   }
   else
   {
    if (urc_compare(&local(urc), 23))
    {
     say_phrase(24);
     Right();
    }
    else
    {
     if (urc_compare(&local(urc), 24))
     {
      say_phrase(28);
      Back();
     }
     else
     {
      if (urc_compare(&local(urc), 17))
      {
       say_phrase(23);
       Left15();
      }
      else
      {
       if (urc_compare(&local(urc), 19))
       {
        say_phrase(24);
        Right15();
       }
       else
       {
        if (urc_compare(&local(urc), 18))
        {
         say_phrase(60);
         Turn();
        }
        else
        {
         if (urc_compare(&local(urc), 16))
         {
          say_phrase(78);
          Boost();
         }
         else
         {
         }
        }
       }
      }
     }
    }
   }
  }
}
if (urc_compare(&local(urc), 26))
{
  left_arm_r(3);
}
else
{
  if (urc_compare(&local(urc), 27))
  {
   left_arm_r(-3);
  }
  else
  {
   if (urc_compare(&local(urc), 28))
   {
    right_arm_r(3);
   }
   else
   {
    if (urc_compare(&local(urc), 29))
    {
     right_arm_r(-3);
    }
    else
    {
     if (urc_compare(&local(urc), 10))
     {
      if (get(FlagHand) == 0)
      {
       say_phrase(11);
       hand_close(4);
       set(FlagHand,1);
      }
      else
      {
       say_phrase(12);
       hand_open();
       set(FlagHand,0);
      }
     }
     else
     {
      if (urc_compare(&local(urc), 20))
      {
       if (get(FlagHip) == 0)
       {
        base_up();
        set(FlagHip,1);
       }
       else
       {
        base_down();
        set(FlagHip,0);
       }
      }
      else
      {
      }
     }
    }
   }
  }
}
if (urc_compare(&local(urc), 4))
{
  head_pan_r(-4);
}
else
{
  if (urc_compare(&local(urc), 5))
  {
   head_pan(6);
  }
  else
  {
   if (urc_compare(&local(urc), 6))
   {
    head_pan_r(4);
   }
   else
   {
    if (urc_compare(&local(urc), 7))
    {
     head_tilt_r(4);
    }
    else
    {
     if (urc_compare(&local(urc), 8))
     {
      head_tilt(2);
     }
     else
     {
      if (urc_compare(&local(urc), 9))
      {
       head_tilt_r(-4);
      }
      else
      {
       if (urc_compare(&local(urc), 12))
       {
        TakePic();
       }
       else
       {
       }
      }
     }
    }
   }
  }
}
if (urc_compare(&local(urc), 1))
{
  lights(true);
  play_sound(1);
  lights(false);
}
else
{
  if (urc_compare(&local(urc), 2))
  {
   led_blink(LED_RED);
   play_sound(2);
   led_off(LED_RED);
  }
  else
  {
   if (urc_compare(&local(urc), 3))
   {
    led_blink(LED_GREEN);
    play_sound(5);
    if (get(FlagD1) == 0)
    {
     led_off(LED_GREEN);
    }
    else
    {
     led_off(LED_GREEN);
     led_on(LED_GREEN);
    }
   }
   else
   {
    if (urc_compare(&local(urc), 13))
    {
     if (get(FlagD1) == 0)
     {
      led_on(LED_GREEN);
      set(FlagD1,1);
     }
     else
     {
      led_off(LED_GREEN);
      set(FlagD1,0);
     }
    }
    else
    {
     if (urc_compare(&local(urc), 14))
     {
      if (get(FlagD2) == 0)
      {
       led_on(LED_YELLOW);
       set_output(3,ACTIVE);
       set(FlagD2,1);
      }
      else
      {
       led_off(LED_YELLOW);
       set_output(3,INACTIVE);
       set(FlagD2,0);
      }
     }
     else
     {
      if (urc_compare(&local(urc), 15))
      {
       if (get(FlagD3) == 0)
       {
        set_output(4,ACTIVE);
        set(FlagD3,1);
       }
       else
       {
        set_output(4,INACTIVE);
        set(FlagD3,0);
       }
      }
      else
      {
       if (urc_compare(&local(urc), 99))
       {
        if (get(FlagD4) == 0)
        {
         lights(true);
         set(FlagD4,1);
        }
        else
        {
         lights(false);
         set(FlagD4,0);
        }
       }
       else
       {
       }
      }
     }
    }
   }
  }
}
msleep(800);
}

void Forward()
{
if (get(Flag1) == 8)
{
  Stop();
}
else
{
}
led_off(LED_ALL);
led_on(LED_GREEN);
unsigned char buf;
buf = 0X02;
i2c_write(42,1,&buf,1);
buf = 0X00;
i2c_write(42,11,&buf,1);
i2c_write(42,12,&buf,1);
set(Flag1,20);
set(FlagLR,0);
}

void Back()
{
if (get(Flag1) >= 20)
{
  Stop();
}
else
{
}
if (get(Flag1) != 8)
{
  led_off(LED_ALL);
  led_blink(LED_YELLOW);
  move_speed(-20);
  move_speed(-40);
  move_speed(-60);
  set(Flag1,8);
}
else
{
}
set(FlagLR,0);
}

void Stop()
{
led_off(LED_ALL);
led_on(LED_RED);
base_stop();
set(Flag1,0);
set(FlagLR,0);
}

void Right()
{
if (get(Flag1) >= 20)
{
  led_off(LED_ALL);
  led_blink(LED_YELLOW_RIGHT);
  if (get(FlagLR) == 1)
  {
   unsigned char buf;
   buf = 0X41;
   i2c_write(42,3,&buf,1);
   buf = 0X00;
   i2c_write(42,11,&buf,1);
   i2c_write(42,12,&buf,1);
   set(FlagLR,2);
  }
  else
  {
   unsigned char buf;
   buf = 0X21;
   i2c_write(42,3,&buf,1);
   buf = 0X00;
   i2c_write(42,11,&buf,1);
   i2c_write(42,12,&buf,1);
  }
  set(FlagLR,1);
}
else
{
  Stop();
  led_off(LED_ALL);
  led_blink(LED_YELLOW_RIGHT);
  turn(45,25);
  led_off(LED_ALL);
}
}

void Left()
{
if (get(Flag1) >= 20)
{
  led_off(LED_ALL);
  led_blink(LED_YELLOW_LEFT);
  if (get(FlagLR) == 5)
  {
   unsigned char buf;
   buf = 0X40;
   i2c_write(42,3,&buf,1);
   buf = 0X00;
   i2c_write(42,11,&buf,1);
   i2c_write(42,12,&buf,1);
   set(FlagLR,6);
  }
  else
  {
   unsigned char buf;
   buf = 0X20;
   i2c_write(42,3,&buf,1);
   buf = 0X00;
   i2c_write(42,11,&buf,1);
   i2c_write(42,12,&buf,1);
  }
  set(FlagLR,5);
}
else
{
  Stop();
  led_off(LED_ALL);
  led_blink(LED_YELLOW_LEFT);
  turn(45,-25);
  led_off(LED_ALL);
}
}

void Init()
{
set(Flag1,0);
set(FlagD1,0);
set(FlagD2,0);
set(FlagD3,0);
set(FlagD4,0);
set(FlagHand,0);
set(FlagHip,0);
set(FlagFine,0);
set(FlagLR,0);
config_gpio(3,OUTPUT);
config_gpio(4,OUTPUT);
HomePos();
say_phrase(114);
led_off(LED_ALL);
led_blink(LED_GREEN);
say_phrase(21);
led_off(LED_ALL);
}

void Fine()
{
Stop();
led_off(LED_ALL);
led_blink(LED_GREEN);
set(FlagFine,1);
HomePos();
if (get(FlagHand) == 1)
{
  hand_open();
}
else
{
}
lights(false);
set_output(3,INACTIVE);
set_output(4,INACTIVE);
led_off(LED_ALL);
}

void Right15()
{
Stop();
led_off(LED_ALL);
led_blink(LED_YELLOW_RIGHT);
turn(15,20);
led_off(LED_ALL);
set(FlagLR,0);
}

void Left15()
{
Stop();
led_off(LED_ALL);
led_blink(LED_YELLOW_LEFT);
turn(15,-20);
led_off(LED_ALL);
set(FlagLR,0);
}

void Turn()
{
Stop();
led_off(LED_ALL);
led_blink(LED_YELLOW_RIGHT);
turn(180,25);
led_off(LED_ALL);
set(FlagLR,0);
}

void HomePos()
{
set_blocking(false);
head_tilt(2);
if (get(FlagFine) == 0)
{
  left_arm(15);
  right_arm(7);
}
else
{
  left_arm(0);
  right_arm(0);
}
base_down();
lights(false);
set_blocking(true);
head_pan(6);
}

void TakePic()
{
led_blink(LED_RED);
say_phrase(58);
if (get(FlagD2) == 0)
{
  led_on(LED_YELLOW);
  set_output(3,ACTIVE);
}
else
{
}
take_picture();
play_sound(11);
led_off(LED_RED);
if (get(FlagD2) == 0)
{
  led_off(LED_YELLOW);
  set_output(3,INACTIVE);
}
else
{
}
}

void Boost()
{
if (get(Flag1) == 8)
{
  Stop();
}
else
{
}
led_off(LED_ALL);
led_on(LED_GREEN);
led_blink(LED_RED);
unsigned char buf;
buf = 0X42;
i2c_write(42,1,&buf,1);
buf = 0X00;
i2c_write(42,11,&buf,1);
i2c_write(42,12,&buf,1);
set(Flag1,21);
set(FlagLR,0);
}

ここから上です-------------------------------------
   

◇一般テレビリモコン用
ここから下です------------------------------
/**
*
* @author fumi
* @version 1.0
*/

#include "c-like.h"
#include "robot.h"

counter Flag1 = new(counter);
counter FlagD1 = new(counter);
counter FlagD2 = new(counter);
counter FlagD3 = new(counter);
counter FlagHand = new(counter);
counter FlagHip = new(counter);
counter FlagD4 = new(counter);
counter FlagFine = new(counter);
counter FlagLR = new(counter);

declare( behavior(Action) );

void Forward();
void Back();
void Stop();
void Right();
void Left();
void Init();
void Fine();
void Right15();
void Left15();
void Turn();
void HomePos();
void TakePic();
void Boost();

define( behavior(Main))
{
Init();
start(Action);
}

define( behavior(Action) )
{
local(urc) = wait_for (urc, update);
if (urc_compare(&local(urc), 0))
{
  say_phrase(4);
  Fine();
  say_phrase(22);
  stop(Action);
}
else
{
}
if (urc_compare(&local(urc), 5))
{
  say_phrase(27);
  Forward();
}
else
{
  if (urc_compare(&local(urc), 7))
  {
   say_phrase(23);
   Left();
  }
  else
  {
   if (urc_compare(&local(urc), 8))
   {
    say_phrase(4);
    Stop();
   }
   else
   {
    if (urc_compare(&local(urc), 9))
    {
     say_phrase(24);
     Right();
    }
    else
    {
     if (urc_compare(&local(urc), 11))
     {
      say_phrase(28);
      Back();
     }
     else
     {
      if (urc_compare(&local(urc), 4))
      {
       say_phrase(23);
       Left15();
      }
      else
      {
       if (urc_compare(&local(urc), 6))
       {
        say_phrase(24);
        Right15();
       }
       else
       {
        if (urc_compare(&local(urc), 12))
        {
         say_phrase(60);
         Turn();
        }
        else
        {
         if (urc_compare(&local(urc), 2))
         {
          say_phrase(78);
          Boost();
         }
         else
         {
         }
        }
       }
      }
     }
    }
   }
  }
}
if (urc_compare(&local(urc), 1))
{
  TakePic();
}
else
{
  if (urc_compare(&local(urc), 3))
  {
   led_blink(LED_RED);
   play_sound(2);
   led_off(LED_RED);
  }
  else
  {
   if (urc_compare(&local(urc), 10))
   {
    if (get(FlagHand) == 0)
    {
     say_phrase(11);
     hand_close(4);
     set(FlagHand,1);
    }
    else
    {
     say_phrase(12);
     hand_open();
     set(FlagHand,0);
    }
   }
   else
   {
    if (urc_compare(&local(urc), 20))
    {
     if (get(FlagHip) == 0)
     {
      base_up();
      set(FlagHip,1);
     }
     else
     {
      base_down();
      set(FlagHip,0);
     }
    }
    else
    {
    }
   }
  }
}
msleep(800);
}

void Forward()
{
if (get(Flag1) == 8)
{
  Stop();
}
else
{
}
led_off(LED_ALL);
led_on(LED_GREEN);
unsigned char buf;
buf = 0X02;
i2c_write(42,1,&buf,1);
buf = 0X00;
i2c_write(42,11,&buf,1);
i2c_write(42,12,&buf,1);
set(Flag1,20);
set(FlagLR,0);
}

void Back()
{
if (get(Flag1) >= 20)
{
  Stop();
}
else
{
}
if (get(Flag1) != 8)
{
  led_off(LED_ALL);
  led_blink(LED_YELLOW);
  move_speed(-20);
  move_speed(-40);
  move_speed(-60);
  set(Flag1,8);
}
else
{
}
set(FlagLR,0);
}

void Stop()
{
led_off(LED_ALL);
led_on(LED_RED);
base_stop();
set(Flag1,0);
set(FlagLR,0);
}

void Right()
{
if (get(Flag1) >= 20)
{
  led_off(LED_ALL);
  led_blink(LED_YELLOW_RIGHT);
  if (get(FlagLR) == 1)
  {
   unsigned char buf;
   buf = 0X41;
   i2c_write(42,3,&buf,1);
   buf = 0X00;
   i2c_write(42,11,&buf,1);
   i2c_write(42,12,&buf,1);
   set(FlagLR,2);
   set(FlagLR,2);
  }
  else
  {
   unsigned char buf;
   buf = 0X21;
   i2c_write(42,3,&buf,1);
   buf = 0X00;
   i2c_write(42,11,&buf,1);
   i2c_write(42,12,&buf,1);
  }
  set(FlagLR,1);
}
else
{
  Stop();
  led_off(LED_ALL);
  led_blink(LED_YELLOW_RIGHT);
  turn(45,25);
  led_off(LED_ALL);
}
}

void Left()
{
if (get(Flag1) >= 20)
{
  led_off(LED_ALL);
  led_blink(LED_YELLOW_LEFT);
  if (get(FlagLR) == 5)
  {
   unsigned char buf;
   buf = 0X40;
   i2c_write(42,3,&buf,1);
   buf = 0X00;
   i2c_write(42,11,&buf,1);
   i2c_write(42,12,&buf,1);
   set(FlagLR,6);
  }
  else
  {
   unsigned char buf;
   buf = 0X20;
   i2c_write(42,3,&buf,1);
   buf = 0X00;
   i2c_write(42,11,&buf,1);
   i2c_write(42,12,&buf,1);
  }
  set(FlagLR,5);
}
else
{
  Stop();
  led_off(LED_ALL);
  led_blink(LED_YELLOW_LEFT);
  turn(45,-25);
  led_off(LED_ALL);
}
}

void Init()
{
set(Flag1,0);
set(FlagD1,0);
set(FlagD2,0);
set(FlagD3,0);
set(FlagD4,0);
set(FlagHand,0);
set(FlagHip,0);
set(FlagFine,0);
set(FlagLR,0);
config_gpio(3,OUTPUT);
config_gpio(4,OUTPUT);
HomePos();
say_phrase(114);
led_off(LED_ALL);
led_blink(LED_GREEN);
say_phrase(21);
led_off(LED_ALL);
}

void Fine()
{
Stop();
led_off(LED_ALL);
led_blink(LED_GREEN);
set(FlagFine,1);
HomePos();
if (get(FlagHand) == 1)
{
  hand_open();
}
else
{
}
lights(false);
set_output(3,INACTIVE);
set_output(4,INACTIVE);
led_off(LED_ALL);
}

void Right15()
{
Stop();
led_off(LED_ALL);
led_blink(LED_YELLOW_RIGHT);
turn(15,20);
led_off(LED_ALL);
set(FlagLR,0);
}

void Left15()
{
Stop();
led_off(LED_ALL);
led_blink(LED_YELLOW_LEFT);
turn(15,-20);
led_off(LED_ALL);
set(FlagLR,0);
}

void Turn()
{
Stop();
led_off(LED_ALL);
led_blink(LED_YELLOW_RIGHT);
turn(180,25);
led_off(LED_ALL);
set(FlagLR,0);
}

void HomePos()
{
set_blocking(false);
head_tilt(2);
if (get(FlagFine) == 0)
{
  left_arm(15);
  right_arm(7);
}
else
{
  left_arm(0);
  right_arm(0);
}
base_down();
lights(false);
set_blocking(true);
head_pan(6);
}

void TakePic()
{
led_blink(LED_RED);
say_phrase(58);
if (get(FlagD2) == 0)
{
  led_on(LED_YELLOW);
  set_output(3,ACTIVE);
}
else
{
}
take_picture();
play_sound(11);
led_off(LED_RED);
if (get(FlagD2) == 0)
{
  led_off(LED_YELLOW);
  set_output(3,INACTIVE);
}
else
{
}
}

void Boost()
{
if (get(Flag1) == 8)
{
  Stop();
}
else
{
}
led_off(LED_ALL);
led_on(LED_GREEN);
led_blink(LED_RED);
unsigned char buf;
buf = 0X42;
i2c_write(42,1,&buf,1);
buf = 0X00;
i2c_write(42,11,&buf,1);
i2c_write(42,12,&buf,1);

set(Flag1,21);
set(FlagLR,0);
}

ここから上です-------------------------------------
 

◇ご注意
尚、動作に関しましては、プログラムが正常に処理されて、ロボ君の各機能が動作する状態にあり、且正しく動いてくれて・・・という前提条件が付きます。
また、検証途中でもありますので、プログラミングミスが多々あるかと思います。
実際に走行させる方は、思わぬ動きをする場合もありますので、広めの場所で、周囲の安全を確認してから、注意をはらいながら走行させる必要があります。
もし、動作中にロボ君が何かに引っかかってそのままにしていると、モーターが止まり過電流が流れ、ボードから煙が・・・などのトラブルも考えられます。
ロボ君がひっかかったらすぐに持ち上げ、速やかに電源を切るなどの処理が必要です。
ご使用にあたっては、あくまでも自己責任でお願いします。

また、実際に検証された方で、バグ等お気付きの点がございましたら、是非、ご意見をコメントでお寄せ下さい。
(2008/1/19)

■あとがき
年末に体調を崩して以来、やっとID-01の作業を開始できました。
今回の作業は、以前作成したプログラムの手直しでしたので、比較的容易にとりかかれました。

|

« 週刊myRobotちょっとひといき(5) | トップページ | 週刊myRobotちょっとひといき(6) »

コメント

KENさん こんにちは。

KENさんのブログで、ユニリモコンの関係記事をご紹介頂きまして、誠に有難うございます。

テレビリモコンからID-01をコントロールするという、一方通行の通信ではありますが、なかなk面白いテストが出来ました。
併せてKENさんの記事を読み、”I2Cプロトコル”の仕組みを応用させて頂き、動きのバリエーションが広げる事が出来ました。

この次は、逆方向通信でのコントロール、つまりID-01で・・・をコントロールするというテストを始めたところです。

本来は、双方向通信を始めたかったのですが、ID-01から行う送信でのノノウハウをあれこれテストしてからにしようと思っています。

また、色々、ご指導賜りたいと思います。
宜しくお願いします。

投稿: ふみのへや | 2008年1月28日 (月) 20:32

KENです。

リモコンの素晴らしいコマンドセット方法、

わたしのブログで紹介させていただきました。

ありがとうございます。

これからも、どんどん、斬新なアイデアを出し続けてください。

ユニバーサル赤外線リモコンを使って
http://blogs.yahoo.co.jp/myrobot_ken/28704747.html

投稿: KEN | 2008年1月28日 (月) 20:09

po_oqさん こんにちは
こちらこそ ご無沙汰しております。

秋葉原の帰りに、上野の「ロボット博」を見に行きましたが、残念ながら休館日で、寒い公園付近をぶらりと一周し、すごすご引き上げてきました。
3月過ぎからは、見事な桜並木が見られるのですが残念です。

「前進+旋回コマンド」で「穏旋回」になるとのレポートですが、こちらでも動作を確認しました。
なるほど、マニュアルににも記載されていない、大発見ですね。

今回公表したプログラムは、「Boost(疾走)機能」を使用するため、「前進」及び「穏旋回」については”I2Cプロトコル”で統一しております。「後退」及び「角度指定旋回」は必ず一旦停止のプロセスを経ております。
両者を混在させると、ガクガクと不安定な動作になるため、それを回避するためのやむなき対応です。

「Boost(疾走)機能」を除いた場合は、全部VCLでプログラミングが可能という事で、今後の応用プログラムに利用させて頂きたいと思います。

po_oqさん、有益なコメントを有難うございました。

投稿: ふみのへや | 2008年1月21日 (月) 17:20

ふみのへやさん おはようございます
ご無沙汰しております
緩やかなカーブですが、前進と左または右の組み合わせを使用するとVCLEでも出来ると思います
参考URL
http://pooq.blog.shinobi.jp/Entry/366/
ふみのへやさんがお考えの動作と異なるようでしたら通り過ごしてください

投稿: po_oq | 2008年1月21日 (月) 07:01

コメントを書く



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


コメントは記事投稿者が公開するまで表示されません。



« 週刊myRobotちょっとひといき(5) | トップページ | 週刊myRobotちょっとひといき(6) »