【C#連載】スライダーでサーボを動かす

お知らせ

皆さん、こんにちは。
RoboCupに熱中しすぎでブログネタの仕込みを忘れたyukiです。公開が遅くなってすみません。m(..)m

RoboCup小型リーグ車輪型の決勝戦では、白熱した延長戦の末、RoboDragons(愛知県立大、日本)が、世界大会4連覇中のSkuba(カササート大学、タイ)を破って優勝しました。6月にオランダである世界大会でもがんばって欲しいなと思います。

RoboCupでもシリアル通信は多用されていて、ロボットの無線通信はシリアル送信や、Ethernetを使ったものがメインです。RoboCupだけでなく、ロボット用のアプリケーションは、シリアル通信がいろいろな場面で役に立ちますのでしっかり覚えて使いこなしてください。

そういえば、そろそろExpressはお試し期間が過ぎると思います。正規ライセンスを使うことは、開発者の権利を尊重することでもありますので、ソフトウェアプログラマの心構えとしてもとても大事なことです。このまま学習を続ける方は、Expressは評価目的ですので、せめてMSのアンケートに答えてあげるなどして、プロダクトキーをゲットしてください。大学等の学生であればアカデミック価格もありますし、学校単位でライセンス持っているところもすくなくないとおもいますので所属先のしかるべき部署に問い合わせてみてくださいね。また、お仕事に使う方は、必ず製品版も買ってくださいね。

さて、今回はスライダー(プログラムではTrackbar)を使って、位置制御でサーボを動かしていきます。まずは先週のプログラムを見てください。

これまでのプログラムとデザインに追加することにして、ここにスライダーを設置するために、枠を広げます。(Width=500くらい)
20130508_blog1

大体、下図のようにwidth=500くらいでいいでしょう。プロパティで変える場合は、sizeを変えてください。
20130508_blog2

次にTrackbarをこのForm1の上に持ってきます。
20130508_blog3

Trackbarが持ってこられたら、画面のように小さいので、設定を変更して見やすくします。
20130508_blog4

Trackbar設定の次の項目を変更します。
サイズは、width=400, height=45くらい(お好みで変えてください。)
20130508_blog5

Maximum=4095(Dynamixel MX-64Rの範囲は0~4095までなので最大値4095をセット)
Minimum=0 
20130508_blog6

Valueは中点=0°の(4096/2)=2048を設定します。
20130508_blog8

また、メモリが細かすぎるので、TrackFrequency=100にしておきます。(自分の好みで決めていただいてかまいません)
20130508_blog7

次にLabelを持ってきて、中点の0を入れます。
20130508_blog9

Labelの変更の仕方は前に説明したとおりです。
20130508_blog10

次は関数を準備します。
赤枠の雷マークをクリックして、”Scroll”の関数をダブルクリックして準備します。
20130508_blog11

これでTrackbarの準備はできました。
ここまでできたら、次は、Timerをドラッグアンドドロップします。

20130508_blog12

次にTimer1の関数を準備します。
赤枠をクリックして、イベントプロパティを呼び出し、”Tick”の関数をダブルクリックして空の関数を準備します。
20130508_blog13
できたかどうか確認してください。
20130508_blog14

また赤枠をクリックしてプロパティに戻り、Interval=20になるように設定します。
20130508_blog15

Dynamixel MX-64Rの処理タイミングは10msくらいですので、今回はそれほど早くなくてもよいので、tickが起動する間隔(Interval)を20msくらいに設定して指令を送ります。この間隔があまり早すぎても通信量が多くなりすぎてトラフィックジャムを起こして、おかしくなります。

20msでも試す分には十分すぎるスピードです。この辺のトラフィックジャムを起こさない秒数はDynamixelの通信間隔のデフォルト値もありますので、その辺も考慮しながら(お使いのPCシステムによっても異なります)、ちょうどよいところを探していろいろ試してみてください。

そして、Timer1を動かすために、Enabled=trueにします。
20130508_blog16

さて。ではプログラムを下記のように追加してください。
例によって、ハイライト部分は、自動で追加されない部分です。

        //角度のグローバル変数
        private int degree=0; //スライダーから取得した角度
        private int packet_flag = 0; //パケットを送ったかどうかを示すフラグ

        //Dynamixel MX-64Rのアドレスマップより
        public const int GOAL_POSITION_L = 0x1E; //サーボの目標角度
        public const int INST_WRITE = 3; //書き込み

        private void trackBar1_Scroll(object sender, EventArgs e)
        {
            degree = trackBar1.Value; //スライダーの設定位置の取得(=角度値)
            packet_flag = 1;
        }

//パケットを作る関数
        private void make_packet(int id, int com, byte[] data, int size)
        {
            byte[] packet = new byte[6+size];
            int offset = 0;
            int len = size+2;

            packet[offset++] = 0xFF; //ヘッダー
            packet[offset++] = 0xFF; //ヘッダー
            packet[offset++] = (byte)(id&0xFF); //サーボのID
            packet[offset++] = (byte)(len&0xFF); //変数の長さ
            packet[offset++] = (byte)com; //コマンド(書き込みか読み込みか)
            //データ分のパケット作成
            for (int i = 0; i < size; i++)
            {
                packet[offset++] = data[i];
            }
            packet[offset++] = calc_checksum_robotis(packet); //チェックサムの計算

      //パケットをシリアルポートから送出
            if (serialPort1.IsOpen == true)
            {
                serialPort1.Write(packet, 0, offset);
                packet_flag = 0;
            }
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            int id = 1;
            byte[] data = new byte[3];
            int size = 0;

            if (packet_flag == 1)
            {
                data[size++] = GOAL_POSITION_L;
                data[size++] = (byte)((degree & 0xFF00)>>8);
                data[size++] = (byte)(degree & 0xFF);
                make_packet(id, INST_WRITE, data, size);                
            }
        }

さてさて。できましたか?
動きましたか?w
日付変更ぎりぎりになってアップだったので、来週は早めにアップします。

【関連商品】

MX64 kit
MX-64Rスターターセット購入ページへ
Dynamixel
Dynamixelショップページ

ROBOTIS関連商品ページ

タイトルとURLをコピーしました