ブログ - 最新エントリー

JavaでDXLIB2を動かす

カテゴリ : 
雑記
2011-1-17 17:02
じゃばじゃばうるさいので、お試しとしてJavaからDXLIB2を動かすサンプルを作成してみた。
検証した環境は以下の通り。
お試しという事もあり、細かい事は抜きに動けばOKといったノリで条件付け。
  • DXLIB2を直接呼出すことはできないため、一旦ラッピング用DLLを作成する。
  • ラッピング関数名は使用するJavaのクラス名に依存。
  • unsigned short型やlong型はJava上でintとして使用する。
    必要に応じてラッピング関数内で型変換。
  • 全て同一フォルダ内に収める。
  • コンパイラ等へのパスは適宜通しておく。
スペースの都合かなり端折ってるが、こんな感じでやるのかなといった雰囲気だけ。
  1. Javaソース
    サンプルとして0~253のIDにPingを発行して結果をプロンプトに表示するソース。
    <SMPL1.java>
    public class SMPL1 {
      private native int DxOpenPort( String com, int br );
      private native boolean DxClosePort( int devid );
      private native boolean DxPing( int devid, int uid, int tout, char[] terr );
      static {
        System.loadLibrary( "dxtest" );  // 今回作成するラッピング用DLL(dxtest.dll)
      }
      public static void main( String args[] ) {
        String COMPORT = "\\\\.\\COM3";  // COMポート名
        int BUADRATE = 1000000;  // ボーレート
        int TIMEOUT = 50;  // タイムアウト
        char terr[] = new char[1];
        int devid, i;
        String msg = "Ping to ID:", mrk = "\n";
        SMPL1 me = new SMPL1();
        devid = me.DxOpenPort( COMPORT, BUADRATE );
        if ( devid != 0 ) {
          for ( i = 0; i < 253; i++ ) {
            if ( me.DxPing( devid, i, TIMEOUT, terr ) ) {
              System.out.printf( "\nPing to ID:%d...OK", i );
              mrk = "\n";
            }
            else {
              System.out.printf( "%sPing to ID:%d...NG(%x)", mrk, i, (int)terr[0] );
              mrk = "\r";
            }
          }
          if ( !me.DxClosePort( devid ) ) System.out.printf( "Close error\n" );
        }
        else
          System.out.printf( "Port not open\n" );
      }
    }

  2. ラッピング関数名の取得
    a). Javaソースをコンパイル(SMPL1.classを作成)。
    >javac SMPL1.java
    b). ヘッダファイルを作成(SMPL1.hを作成)。
    >javah -classpath . -d . SMPL1
    以下作成されるヘッダファイルの抜粋。
    <SMPL1.h>
    JNIEXPORT jint JNICALL Java_SMPL1_DxOpenPort  (JNIEnv *, jobject, jstring, jint);
    JNIEXPORT jboolean JNICALL Java_SMPL1_DxClosePort  (JNIEnv *, jobject, jint);
    JNIEXPORT jboolean JNICALL Java_SMPL1_DxPing  (JNIEnv *, jobject, jint, jint, jint, jcharArray)

  3. Cソース作成
    a). SMPL1.hをdxtest.cに変更。
    b). ラッピング関数の中身を作成。
    JavaとDLLの仲介役だが、相互の規約を気にしないと話にならない。とりあえず最低限必要なOpen/Close/Pingだけ作った。
    <dxtest.c>
    #define __MAKE_LIB__
    #include <stdio.h>
    #include <stdlib.h>
    #include <jni.h>
    #include "dxlib2.h"
    JNIEXPORT jint JNICALL Java_SMPL1_DxOpenPort
      (JNIEnv *env, jobject jobj, jstring pCom, jint br) {
      DXDEVICEID dev;
      char *port;
      int sz = (*env)->GetStringLength( env, pCom );
      // java文字列より取得
      const char *comPort = (*env)->GetStringUTFChars( env, pCom, 0 );
      port = (char *)malloc( sz + 1 );
      strcpy( port, comPort );
      port[strlen(port)] = 0x0;
      dev = DX_OpenPort( port, br );  // dxlib2.dllのDX_OpenPort()の呼出し
      // memory解放
      free( port );
      (*env)->ReleaseStringUTFChars( env, pCom, comPort );
      return (jint)dev;
    }
    JNIEXPORT jboolean JNICALL Java_SMPL1_DxClosePort
     (JNIEnv *env, jobject jobj, jint id) {
      return DX_ClosePort( (DXDEVICEID)id );
    }
    JNIEXPORT jboolean JNICALL Java_SMPL1_DxPing
      (JNIEnv *env, jobject jobj, jint devid, jint id, jint tout, jcharArray terr) {
      TDxErrorCode  err;
      BOOL      bResult;
      UCHAR   uID;
      jchar        *arrays; // local領域
      int             sz;         // 配列size
      jboolean jbl;         // isCopy
      uID = (UCHAR)(id & 0x00ff);
      bResult = DX_Ping( (DXDEVICEID)devid, uID, tout, &err );
      // 配列の取得
      arrays = (*env)->GetCharArrayElements( env, terr, &jbl );
      if ( (*env)->GetArrayLength( env, terr ) > 0 ) arrays[0] = err;
      // 配列の解放(Javaへ適用)
      (*env)->ReleaseCharArrayElements( env, terr, arrays, 0 );
      return bResult;
    }

  4. DLL作成
    a). dxtest.cをDLLにする。
    >gcc -shared -o dxtest.dll dxtest.c -l dxlib2 -Wl,-kill-at -I Javaのincludeパス -I Javaのincludeパス\win32 -L .
    Javaのincludeパスに空白が含まれている場合はダブルクォーテーションで括る等の措置を講じるべし。

  5. 実行
    a). 以下のDLLとクラスファイルが同じフォルダに存在していることを確認。
    SMPL1.class  dxtest.dll  dxlib2.dll
    b). おもむろにコマンドプロンプトで実行
    >java SMPL1
    実行結果はこんな感じになるだろうか。

雑感、何が楽しいのかさっぱり・・・。

インターンシップ

カテゴリ : 
その他
2011-1-17 13:59
今年も3ヵ月間電子回路・プログラミングなどを学びに、海外から研修に来ている女子学生がいます。
来日した当初は挨拶以外の日本語ができず、コミュニケーションは全て片言の英語。既に1ヵ月が経った事もあり、日常会話であれば多少なりとも何が通じる様になりましたが。
おかげで私のボディーランゲージの勉強になりましたw。

自学自習にも熱心に取り組んでくれるおかげで、毎日夜遅くまで帰ってくれません。しかし、プログラム言語と電子回路はほぼ世界共通ですので、ここで得た知識が将来役に立つ日が来る事でしょう。

日本にもこういった学生がもっと増えると嬉しいですねぇ。

Dynamixel Library2の64bit対応

カテゴリ : 
その他
2010-12-6 19:13
今週中には詳細と正式版を公開する予定ですが、多少ご要望がありましたWindowsの64bitネイティブに対応中です。とはいっても単にコンパイラが64bitに対応していれば良いまでで、インストーラのサイズが肥大化するのですが同梱する方向で検討しています。

その他に先に問題を言ってしまうと、実際には正常に処理されている通信がWindowsからの応答遅延によりタイムアウトになるといったケースは回避不能ですので悪しからず。
また、ftdi社の仮想シリアルドライバが頻繁にバージョンアップしている様なので、PCに合わせてドライバのバージョンを選ばないとパフォーマンスに影響を及ぼす様です。

MATLAB EXPO 2010

カテゴリ : 
イベント
2010-11-30 17:38
11月26日(金)に開催されましたMATLAB EXPO 2010展示コーナーにおいて、弊社のコントローラおよびDynamixel RX-28を使用したロボットアームを展示していただきました。

MATLAB Simulinkのリアルタイムシミュレーションを使用したアプリケーションの紹介として、Windows上のMATLABからDynamixelコンフィギュレータを介してロボットアームをコントロールするデモを行いました。



また、MATLAB上のソースをEmbedded Corderで組み込み向けマイコンのソースに変換し、FDIII-HCから制御させるといった手法も紹介しました。



低コストなMATLAB Simulinkの教材です。ご興味をお持ちの方は弊社にお問い合わせ下さい。

FDIIIでToppers

カテゴリ : 
TOPPERS
2010-11-16 22:17
FDIII-HCのブートローダのアップデートと同時に、GCC Developer Liteも新しいライブラリを同梱して公開する旨のニュースがありました。
実際何をやってるかというと、ToppersをFDIII-HCに適用するネタでして、本家ではかなり昔から移植されていたのですが、とっても煩雑なためにGCC Developer Liteのライブラリとして同梱させるまでには至っていませんでした。
既にAT91SAM7S単体とUD3でToppersが使用できるようになっているので、そのリソースを利用してユーザーアプリケーション内でマルチタスクが実現できるように仕込中といった所です。

従来のインターバル割り込みで駆動される似非タスクでは即時復帰を要求されるために、処理時間が長いサブルーチンをバックグラウンドで走らせることができなかったのですが、Toppersのタスクを使用していろんなことを同時にかつテキトーに動かすなんて事が簡単になるはず。

公開までもう少しだけお待ちください。

Androidで台車コントロール

カテゴリ : 
その他
2010-11-12 19:03


Android携帯で台車を動かしました。
Androidアプリ上のボタン操作で前進・後進・旋回。
自動モードにすると、台車に搭載したセンサの状態によってAndroidが「警告!」や「きゃー」と音を発します。
Androidと台車はBluetoothで通信。
台車はFDIII-HC、Dynamixel RX-28、Multifunction I/Oモジュール、反射型フォトインタラプタ、PSD距離センサで製作しました。
FDIII-HCスターターキットの学習ガイドChapter9を公開しました。
Chapter9では、車輪ロボットでライントレースをする方法を紹介しています。

(追記2010.10.13) より上手くライントレースするプログラムを追記しました。

Linuxで

カテゴリ : 
雑記
2010-10-4 21:52
何度か問い合わせをもらっているLinux対応。ってかGNUの恩恵を与っているに過ぎないので、どちらかというとLinux配下で揃えてもらえればって事なんですが・・・。

とりあえずWine使えばバイナリ自体は動くので、シリアルポート使った代物だけ小細工してあげようかなと考えちう。

ud3

カテゴリ : 
雑記
2010-9-28 21:41
作れど作れど間に合わず、申し訳ありません。。。
もう一点、次回カートが空になると次の充当は来年になりそうです・・・。

P.S.
今のUD3のライブラリはある程度余流があるという感触なので、次回アップデートで以下の機能を盛り込もうと考えています。
  • タスクのスタックとして512byte確保しているが、やりたいことが増えると足りなくなりかねないので、2kbyte程度まで増やす
  • Dynamixelプロトコルのスレーブをサポートしているが、ホストとしても機能させてみたいのでモードの切り替えとAPIを追加する
  • DUALSHOCK3のバッテリ残量が気になるらしいのでモニタできるようにする
  • それらに伴いサンプルプログラムを追加修正
  • プロポの初動位置にパンチを追加
といった所でしょうか。
積極的にタスクをいじり始めてどうやってもおかしげな挙動する事に気付いた。ずーっとコピペで作った別のソースが問題かと思って目を皿のようにして見てても、そこには答えはなかった。
結論から言うとTOPPERSのコンフィギュレーション(正解なのかは別)。適当にCRE_TSKを列挙してちゃいけないみたいなのねん。とりあえずmainタスクを先頭に書いたらRESUMEもSUSPENDも意図した通りに動く様になったので良しとする。

という事で、GCC Developer Liteに入っているSAM7S_TOPPERSのコンフィギュレーションファイルを修正し、舌の根も乾かぬうちにr4として公開。ついでにUD3が金曜日から販売されるらしいので、余計なAPIを追加したものも入れてある。