Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

This article is a Private article. Only a writer and users who know the URL can access it.
Please change open range to public in publish setting if you want to share this article with other users.

More than 5 years have passed since last update.

③ドローンを操作するプログラムの作成

Last updated at Posted at 2019-08-24

トップページへ

##本作業について
タイトル通り、ドローンを操作できる状態にすることを目指します。
そのためにプログラムの作成・追加を行い、キーボードで操作できるようにします。
「コントローラで動かしたい」といった場合でも、このプログラムを少し書き換えることで実現できるようですので、まずはこのページに従ってキーボードで動かしてみてください。

######はしがき:readmeの情報について
AirSim\Unity上では計2つのREADME.mdが存在します。
その内、UnityDemoフォルダ内にある方を開くと「キー入力で操作できる」旨が書いてあります。
しかし、この情報は古いバージョンのものであり、現在のバージョンではキー入力による操作をデフォルトで行うことはできません。

##具体的な作業
この作業は、前回の「Unityへのインポート作業~実行」までを終えていることを前提としています。これらの作業を終えていない方は、先にそちらをご覧ください。

◆手順
①プログラムの書き足し
②プログラムの新規作成
③キーコンフィグの設定
④実行してみる
⑤ドローンの動作の要素について

##①プログラムの書き足し
「AirSim→Unity→UnityDemo→Assets→AirSimAssets→Scripts→Vehicles」内にVehicle.csというc#スクリプトが存在します。
これをVisual Studioで開き、353行目と354行目の間に以下のプログラムを加筆してください。

// Added for DroneControllerInput Use
public bool ControllerAllowed() {
    return isServerStarted && !isApiEnabled;
}

public void SetRCData(AirSimRCData data) {
    rcData = data;
}

##②プログラムの新規作成
DroneControllerInput.csというc#スクリプトを作成します。
ファイルを作成する場所は任意です。
対となる車のコントロールプログラムの場所を意識するなら、"AirSim/Unity/UnityDemo/Assets/AirSimAssets/Scripts/Vehicles/Multirotor/"内が妥当ですが、見ての通りかなり深い位置になってしまいます。
深い位置が嫌いな方であれば、自分にとって分かりやすい場所に作る方が良いでしょう。

プログラムの中身は以下の通りです。

DroneControllerInput.cs
using System;
using System.Collections.Generic;
using AirSimUnity.DroneStructs;
using UnityEngine;

namespace AirSimUnity
{
[RequireComponent(typeof(Drone))]
public class DroneControllerInput : MonoBehaviour
{
private Drone drone;

    private void Start() {
        drone = this.gameObject.GetComponent<Drone>();
    }
    private void LateUpdate()
    {
        if (drone.ControllerAllowed())
        {
            AirSimRCData rcData = drone.GetRCData();

            rcData.is_valid = true;
            rcData.roll = Input.GetAxis("Horizontal"); //左右
            rcData.pitch = Input.GetAxis("Vertical"); //前後
            rcData.throttle = Input.GetAxis("Depth"); //上下
            rcData.yaw = Input.GetAxis("Yaw"); //回転
            rcData.left_z = 0;
            rcData.right_z = 0;

            drone.SetRCData(rcData);
        }
    }
}
}

そして、"DroneDemo"シーンを開き、作成したDroneControllerInput.csをドローンのオブジェクト(QuadCopter)にコンポーネントとして追加してください。
5.png

追加が終わったら、忘れないうちにシーンを"SimModeSelecter"に戻しておきましょう。

ここまでの作業によって、入力設定でキーコンフィグを行うことが可能になります。

##③キーコンフィグの設定
「(メニューバーの)編集→プロジェクト設定→入力」を選択します。
すると、右側に表示されるインスペクターからキーコンフィグを行うことができます。

デフォルトでは「Horizontal(日本語表記:水平)」「Vertical(日本語表記:垂直方向)」の2つは既に作られています。
この他に、「Depth」「Yaw」の2つを作成してください。不要な「Fire1」「Fire2」あたりの名前を変更するのが一番手っ取り早いです。

あとはキーコンフィグを自由に設定してください。
どこに何を設定すればいいかわからない人は、以下のように設定するのがおすすめです。

Horizontalの負方向ボタン left (矢印キー左)
Horizontalの正方向ボタン right (矢印キー右)
Verticalの負方向ボタン down (矢印キー下)
Verticalの正方向ボタン up (矢印キー上)
Depthの負方向ボタン s
Depthの正方向ボタン w
Yawの負方向ボタン a
Yawの正方向ボタン d

##④実行してみる
前回と同じく、"SimModeSelecter"シーンから実行してみましょう。
実際に動かせれば成功です。

先ほどおすすめした通りに設定した場合、
・矢印キーで前後左右
・awsdキーで上下回転
となります。

ちなみに、慣性が強く働いているのは仕様のようです。

##⑤ドローンのカスタマイズ
この項目では、より操作をカスタマイズしたい人に向けて記載しておきます。

###・キー入力の限界
単純なキー入力だけでは、残念ながらドローンの速度を微調整することはできません。
なぜなら、キーボードの入力では「押している」か「押されていない」の2つの状態しか扱えないからです。
よって、「キーを半分押したから半分の速度でドローンを動かす」というのは不可能です。

もし、キーボード上で半分の速度で動かしたいのであれば、後述するような手法で「キーを押すと、50%の速度で動くように設定する」必要があります。
ただ、この要領で「複数のスピードを出せるようにする」場合は一つの機能に対して複数のキーを割り当てる必要があります。
そうなると、操作が複雑になり、実用性が低下しています。

そのため、速度を微調整したい場合にはキーボードをコントローラとして使用するのはあまりオススメできません。
別途コントローラーなど用意し、アナログスティックで操作した方が良いです。

###・速度の変更
キーを押した時の速度を変更したい場合、プログラムの数値を弄ることで簡単に変更することができます。

例えば、「左右を1/2のスピードにしたい!」といった場合には、
先ほどの

rcData.roll = Input.GetAxis("Horizontal");

の部分を

rcData.roll = Input.GetAxis("Horizontal")/2;

と変えるだけで半分になります。

また、if文によっても同じことができますが、その場合は以下の2つに注意してください。
1.必ず、「何も押していないときの動作を定義する」こと。(左右なら、if文の最後に必ずelseでrcData.roll=0を入れる。忘れると永久に押しっぱなし判定になる。)
2.小数の値を代入する際には、float型にする。(忘れると小数点以下切り捨てで扱われる)

##おまけ1:参考にしたページ
本作業の内容は、このページの情報を参考に作成しています。
このページが無ければ、私はAirSimを使うことを断念していました。
この場を借りて、元となるプログラムを作成したjasonhbartlettさんにお礼申し上げます。

##おまけ2:私が使用したプログラム
今回紹介したプログラムとは別に、私が編集したDroneControllerInput.csもここに記しておきます。
先述のものとは、3つの変数によって操作している点が異なります。
ちょっと変わった操作方法ですが、プログラムを読める人であれば、大体何をしているのか想定がつくと思います。参考までに。

DroneControllerInput.cs(ver.2)
using System;
using System.Collections.Generic;
using AirSimUnity.DroneStructs;
using UnityEngine;

namespace AirSimUnity
{
    [RequireComponent(typeof(Drone))]
    public class DroneControllerInput : MonoBehaviour
    {
        private Drone drone;

        private void Start()
        {
            drone = this.gameObject.GetComponent<Drone>();
        }
        private void LateUpdate()
        {
         
            if (drone.ControllerAllowed())
            {
                AirSimRCData rcData = drone.GetRCData();

                rcData.is_valid = true;

                if ((RotateByAccelerometer.Z == 1))
                {
                    //旋回動作
                    rcData.roll = 0;
                    rcData.pitch = 0;
                    
                    if (RotateByAccelerometer.Y > 0.2)
                    {
                        rcData.yaw = (float)0.2;
                    }
                    else if (RotateByAccelerometer.Y < -0.2)
                    {
                        rcData.yaw = (float)-0.2;
                    }
                    else
                    {
                        rcData.yaw = 0;
                    } 
                }
                else
                {
                    rcData.yaw = 0;

                    //左右動作
                    if (RotateByAccelerometer.Y >= 0.7)
                    {
                        rcData.roll = (float)0.5;
                    }
                    else if (RotateByAccelerometer.Y >= 0.4 && 0.7>= RotateByAccelerometer.Y)
                    {
                        rcData.roll = (float)0.25;
                    }
                    else if (RotateByAccelerometer.Y >= 0.2 && 0.4 > RotateByAccelerometer.Y)
                    {
                        rcData.roll = (float)0.1;
                    }
                    else if (RotateByAccelerometer.Y <= -0.7)
                    {
                        rcData.roll = (float)-0.5;
                    }
                    else if (RotateByAccelerometer.Y <= -0.4 && -0.7 <= RotateByAccelerometer.Y)
                    {
                        rcData.roll = (float)-0.25;
                    }
                    else if (RotateByAccelerometer.Y <= -0.2 && -0.4 < RotateByAccelerometer.Y)
                    {
                        rcData.roll = (float)-0.1;
                    }
                    else
                    {
                        rcData.roll = 0;
   
                    }

                    //前後動作
                    if (RotateByAccelerometer.X >= 0.5)
                    {
                        rcData.pitch = (float)0.5;
                    }
                    else if (RotateByAccelerometer.X >= 0.3 && 0.5 >= RotateByAccelerometer.X)
                    {
                        rcData.pitch = (float)0.25;
                    }
                    else if (RotateByAccelerometer.X >= 0.15 && 0.3 > RotateByAccelerometer.X)
                    {
                        rcData.pitch = (float)0.1;
                    }
                    else if (RotateByAccelerometer.X <= -0.6)
                    {
                        rcData.pitch = (float)-0.5;
                    }
                    else if (RotateByAccelerometer.X <= -0.3 && -0.6 <= RotateByAccelerometer.X)
                    {
                        rcData.pitch = (float)-0.25;
                    }
                    else if (RotateByAccelerometer.X <= -0.15 && -0.3 < RotateByAccelerometer.X)
                    {
                        rcData.pitch = (float)-0.1;
                    }
                    else
                    {
                        rcData.pitch = 0;
                    }
                    
                }
                
                rcData.left_z = 0;
                rcData.right_z = 0;

                drone.SetRCData(rcData);
            }
        }
    }
}

前のページに戻る    次のページへ進む>

1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?