2021年8月7日土曜日

MAVIC MINI コントロールスクリプト

この時点で、ドローンをコントロールしているスクリプトは以下のようなものです。もっと、細かい解説が必要ですが、その時間が取れないので、感じだけを味わってください。

------------------------ 以下 ----------------

############
# ユーザースクリプト
# 2021年8月8日 ver.26
# 2021年8月5日 ver.22 単位を全てメートルに変更
# 2021年7月18日 ver.0
############

@grammar
# 音声認識文法
# AmenboScriptと矛盾しない形で入れておく
0: Object + Object + Verb
0: Object + Object + Unit
0: Object + Object + Question
0: Subject + Verb
0: Verb + Negation
0: Subject + Adjective
1: Object + Verb
1: Verb + End
1: Object + End
1: Adjective + End

@concept
# 音声に含まれる概念
Subject : [僕,私]
Object : 顔,口,テスト,角度,周り,距離
Adjective : 嫌い,好き,終わり
Verb : [始め,一,はじめ],キス,見つけ,着陸,見なさ,回転,回り
Unit : メートル
Question : どれ,教え
End : [よ,ます,ましょう,なさい],か,です
Negation : 止め,やめ

@command
# 音声コマンド
始めるよ : ^takeoff() ^sleep(2000) はい、アメンボです。よろしくお願いします ^sleep(1000)
終わります : おわります ^landing()
着陸しなさい : 着陸します ^landing()
僕が好きですか : ^sleep(1000) はい、好きです ^yes()
僕が嫌いですか : ^sleep(1000) いいえ、好きです ^no()
顔を見つけなさい : ^sleep(1000) はい、顔を探します &searchface()
キスをしましょう : ^sleep(1000) はい、キスします &kiss()
テストをします : テストですね ^getaltitude()
口を見なさい : 口を見ます &shapeLip()
角度を見なさい : 角度を見ます &faceAngle()
回転しなさい : 回転します ^hloop(0.5,1.0)
回転止めなさい : 回転やめます ^stophloop()

# 関数やマクロ内の変数は全てグローバル変数
# $distには、&approachefaceで近づいた距離が入っているはず

顔の周りを回りなさい : 顔の周りを回ります &noseincircle($dist)

# $0,$1....の変数は同時にグローバル変数になる
# 関数の引数にはグローバル変数しか使えないので

顔までの距離を $0 メートルにしなさい : 顔まで $0 メートルにします &approacheface($0)
顔までの距離はどれくらいですか : 顔までの距離は $dist メートルです

@macro
# マクロの引数は、$macroarg_0, $macroarg_1,・・・の変数に入っている
# ノーズインサークルの自動実行
# 人の顔が真ん中にあることを前提にする
# 事前に、回転する半径を引数に入れておく
&noseincircle
    let $radius = $macroarg_0
    ^print("マクロ: noseincircle の開始")
    ^speek("顔を中心に旋回をします")
    ^print("顔を中心に旋回をします。半径は",$radius,"メートルです")
    ^hloop($radius,1.0)
    ^print("マクロ: noseincircle を終了")
    ^speek("旋回を終えました")
&&

# 顔を画面の中心にしながら指定した距離まで顔に近づく
# 事前に、変数 $distface に近づく距離(メートル単位)を指定しておく
&approacheface
    let $distface = $macroarg_0
    ^print("マクロ: approacheface の開始")
    # 顔を真ん中にするのに成功していることが前提
    # 顔を真ん中にしないと人との距離が図れない
    ^speek("顔との距離を調整します")
    ^print("顔との距離を",$distface,"メートルに調整します")
    let $maxtry = 10
    for $i=0 ; $i < $maxtry ;$i += 1 {
        let $dist = ^checkface()
        # 目標距離との差が0.1メートル以下になるまで 最大10回
        if ^abs($dist - $distface) < 0.1 && $dist > 0.0 {
            # $dist が -1 は、エラー
            break
        }
        # 接近を刻む距離
        let $unitdist = 0.1
        if $dist > 1.0 {
            ## 1メートル以上離れていたら25センチ移動する
            $unitdist = 0.25
        }
        let $diff = $dist - $distface
        if $diff > 0.0 {
            ^speek($unitdist,"メートル近づきます")
            ^print("No.",$i," 距離差:",$diff," => ",$unitdist,"メートル接近")
            ^forward($unitdist)
            ## 距離の改訂 moveForFaceCenter の引数
            let $reviseddist =  $dist - $unitdist
        }else{
            ^speek($unitdist,"メートル離れます")
            ^print("No.",$i," 距離差:",$diff," => ",$unitdist,"メートル離脱")
            ^backward($unitdist)
            let $reviseddist =  $dist + $unitdist
        }
        # 次のコマンドまで少し時間を空ける
        ^sleep(1000)
        # ここで、再度、顔が正面になるように調整する   
        # $unitdist m近づいたので、その分差し引く
        # 3回に1回は、顔の中心に、調整する
        if $i % 3 == 1 {
            ^speek("顔が中心になるよう再設定します")
            ^print("顔が中心になるよう再設定します")
            ^moveForFaceCenter($reviseddist)
        }
    }
    if ^abs($dist - $distface) < 0.1 && $dist > 0.0 {
        ^speek("距離の調整に成功しました")
        ^print("距離の調整に成功しました")
    }else{
        ^speek("距離の調整に失敗しました")
        ^print("距離の調整に失敗しました")
    }
&&

# 顔の角度で、機体を水平、垂直に動かす
&faceAngle
    ^print("マクロ: faceAngle の開始")
    # 基本的移動距離を定める
    let $movedist = 0.2
    ^print("教授の顔の傾きを観察します")
    ^startFaceStatus()
    let $maxtry = 15 # この回数だけ反応します
    for $i=0 ; $i < $maxtry ; $i += 1 {
        if $i % 4 == 3 {
            let $dist = ^checkface()
            if $dist < 0 {
                # 顔を見失っています
                ^print("顔を見失いました")
                ^sleep(1000) 
            }
            # 4回に1回は顔中心の補正
            #^speek("顔が中心になるよう再設定します")
            ^print("顔が中心になるよう再設定します")
            ^moveForFaceCenter($dist)
            ^sleep(500)
        }else{
            # 中心補正しない場合
            # 1秒待機。これを怠ると、瞬間的に終わる可能性がある
            ^sleep(1000) 
        }
        let $hdist = ^getHorizontalFaceAngle()
        if $hdist > 9000 { # 距離は指数で見ている、メートルでもセンチでもない
            ^print("顔の水平傾斜が取れません ",$i,"回")
            #^speek("顔の水平傾斜が取れません")
            #continue # これがあると縦を見ない
        }
        if $hdist < 9000 && $hdist > 0.55 {
            #^speek("右に動きます")
            ^print("右に",$movedist,"センチ動きます 回数 ",$i)
            ^right($movedist)
            #continue # これがあると縦を見ない
        }
        if $hdist < 0.45 {
            #^speek("左に動きます")
            ^print("左に",$movedist,"センチ動きます 回数 ",$i)
            ^left($movedist)
            #continue # これがあると縦を見ない
        }
        let $vdist = ^getVerticalFaceAngle()
        if $vdist > 9000 {
            ^print("顔の垂直傾斜が取れません ",$i,"回")
            #^speek("顔の垂直傾斜が取れません")
            continue
        }
        if $vdist > 0.6 {
            #^speek("上に動きます")
            ^print("上に",$movedist,"センチ動きます 回数 ",$i)
            ^upward($movedist)
            continue
        }
        if $vdist < 0.45 {
            #^speek("下に動きます")
            ^print("下に",$movedist,"センチ動きます 回数 ",$i)
            ^downward($movedist)
            continue
        }
        #^speek("顔の角度は通常です")
        ^print("顔の角度は通常です 回数 ",$i)
    }
     ^speek("顔の角度の観察を停止します")
     ^print("顔の角度の観察を停止します")
     ^stopFaceStatus()
&&


# 口の形で前後に動かすマクロ
&shapeLip
    ^print("マクロ: shapeLip の開始")
    # 基本的移動距離を定める
    let $movedist = 0.2
    ^print("教授の口を観察します")
    ^startFaceStatus()
    let $maxtry = 15 # この回数だけ口に反応します
    for $i=0 ; $i < $maxtry ; $i += 1 {
        if $i % 4 == 3 {
            let $dist = ^checkface()
            if $dist < 0 {
                # 顔を見失っています
                ^print("顔を見失いました")
                ^sleep(1000) 
            }
            # 4回に1回は顔中心の補正
            #^speek("顔が中心になるよう再設定します")
            ^print("顔が中心になるよう再設定します")
            ^moveForFaceCenter($dist)
            ^sleep(500)
        }else{
            # 中心補正しない場合
            # 1秒待機。これを怠ると、瞬間的に終わる可能性がある
            ^sleep(1000) 
        }
        let $ldist = ^getLipDistance()
        if $ldist < 0 {
            ^print("口の形が取れません ",$i,"回")
            #^speek("口の形が取れません")
            continue
        }
        if $ldist < 0.1 { # 距離は指数で見ている、メートルでもセンチでもない
            #^speek("近づきます")
            ^print("キス型なので",$movedist,"センチ近づきます 回数 ",$i)
            # $movedist m近づく
            ^forward($movedist)
            # 次のコマンドまで少し時間を空ける
            continue
        }
        if $ldist > 0.15 {
            #^speek("離れます")
            ^print("口を開けているので",$movedist,"センチ離れます 回数 ",$i)
            # $movedist cm離れる
            ^backward($movedist)
            # 次のコマンドまで少し時間を空ける
            continue
        }
        #^speek("口の形は通常です")
        ^print("口の形は通常です 回数 ",$i)
    }
     ^speek("口の観察を停止します")
     ^print("口の観察を停止します")
    ^stopFaceStatus()
&&

# 顔を見つけることに限定したマクロ
&searchface
    ^print("マクロ: searchface の開始")
    ^print("身近な顔を探します")
    # ドローンの高度を160センチの、人の標準的身長に設定する
    ^print("ドローンの高度を160センチにします。")
    ^altitude(1.6)
    # FPVに顔がないかチェックする
    # 30度刻みで回転する
    let $flag = 0
    for $i=0 ; $i < 12 ;$i += 1 {
        ^print("角度を 30度 左回転させます")
        #^print("角度を " $i "度 右回転させます")
        # $distは、少数以下が丸められている倍精度数
        let $dist = ^checkface()
        if $dist > 0.1 {
            ^speek("顔を見つけました")
            ^print("顔を見つけました。距離は ",$dist,"cm です")
            $flag = 1
            break
        }
        ^turnleft(30)
        #^rightangle($i)
    }
    if $flag <= 0.1 {
        ^speek("顔が見つかりませんでした")
        ^print("顔が見つかりませんでした")
    }else{
        ^print("顔は見つかりました")
        let $maxtry = 15
        # 顔が見つかった場合の処理
        let $count = $maxtry # $maxtry 回だけ試みる
        ^print("顔が真ん中になるように姿勢を制御します")
        # 最大許容誤差の設定 pxel単位
        let $maxdiffpixel = 70
        # 修正ループの開始
        while ^checkFaceCenter($maxdiffpixel) < 0.1 {
            # まず、顔を真ん中にする
            ^print("顔を正面にします Try No. ",$maxtry-$count)
            ^moveForFaceCenter($dist)
            # 次のコマンドまで少し時間を空ける
            ^sleep(500)
            $count -= 1
            if $count < 0.1 {
                break
            }
        }
        ^print("顔を正面にする試みは終わりました 回数 ",$maxtry-$count)
        if $count > 0.1 {
            # 顔を真ん中にするのに成功した場合
            # 顔を真ん中にしないと人との距離が図れない
            ^speek("顔を真ん中にしました")
            ^print("顔を真ん中にすることに成功しました")
        }else{
            ^speek("顔を真ん中にできませんでした")
            ^print("顔を真ん中にできませんでした")
        }
    }
&&

# 一番近くの人とキスするマクロ
&kiss
    ^print("マクロ: kiss の開始")
    ^print("身近な顔を探します")
    # ドローンの高度を160センチの、人の標準的身長に設定する
    ^print("ドローンの高度を160センチにします。")
    ^altitude(1.6)
    # FPVに顔がないかチェックする
    # 30度刻みで回転する
    let $flag = 0
    for $i=0 ; $i < 12 ;$i += 1 {
        ^print("角度を 30度 左回転させます")
        #^print("角度を " $i "度 右回転させます")
        # $distは、少数以下が丸められている倍精度数
        let $dist = ^checkface()
        if $dist > 0.1 {
            ^speek("顔を見つけました")
            ^print("顔を見つけました。距離は ",$dist,"cm です")
            $flag = 1
            break
        }
        ^turnleft(30)
        #^rightangle($i)
    }
    if $flag <= 0.1 {
        ^speek("顔が見つかりませんでした")
        ^print("顔が見つかりませんでした")
    }else{
        ^print("顔は見つかりました")
        let $maxtry = 15
        # 顔が見つかった場合の処理
        let $count = $maxtry # $maxtry 回だけ試みる
        ^print("顔が真ん中になるように姿勢を制御します")
        # 45ピクセル以内にしている
        while ^checkFaceCenter(45.0) < 0.1 {
            # まず、顔を真ん中にする
            ^print("顔を正面にします Try No. ",$maxtry-$count)
            ^moveForFaceCenter($dist)
            # 次のコマンドまで少し時間を空ける
            ^sleep(500)
            $count -= 1
            if $count < 0.1 {
                break
            }
        }
        ^print("顔を正面にする試みは終わりました 回数 ",$maxtry-$count)
        if $count > 0.1 {
            # 顔を真ん中にするのに成功した場合
            # 顔を真ん中にしないと人との距離が図れない
            ^speek("顔を真ん中にしました もっと近づきます")
            ^print("顔を真ん中にすることに成功しました。顔に近づいていきます")
            for $i=0 ; $i < $maxtry ;$i += 1 {
                let $dist = ^checkface()
                # 25センチ以下になるまで近づく 最大10回
                if $dist < 0.25 && $dist > 0.0 {
                    # $dist が -1 は、エラー
                    # 0.0 < $dist < 35.0 を最接近とする
                    break
                }
                ^speek("10センチ近づきます")
                ^print("10センチ近づきます 回数 ",$maxtry-$count)
                # 10cmずつ近づく
                ^forward(0.1)
                # 次のコマンドまで少し時間を空ける
                ^sleep(1000)
                # ここで、再度、顔が正面になるように調整する   
                # 10cm近づいたので、その分差し引く
                # 3回に1回は、顔の中心に、調整する
                if $i % 3 == 1 {
                    ^speek("顔が中心になるよう再設定します")
                    ^print("顔が中心になるよう再設定します")
                    ^moveForFaceCenter($dist-0.25)
                }
            }
            if $dist < 0.25 && $dist > 0.0 {
                ^speek("もう、キスできます")
                ^print("もう、キスできます")
            }else{
                ^speek("近づくことができませんでした")
                ^print("近づくことができませんでした")
            }
        }else{
            ^speek("顔を真ん中にできませんでした")
            ^print("顔を真ん中にできませんでした")
        }
    }
&&

### Script End ###

0 件のコメント:

コメントを投稿

立ち上がらないraspberrypiのネットワーク

 raspberrypiのネットワークが立ち上がらなくなってしまっていた。差し当たって必要ないのでほっておいたが、今日、いろいろ調べてみた。 結局、raspi-confgで、network Configure をdhcpcdから、networkmanagerに変更したら立ち上がる...