Esempio n. 1
0
        /// <summary>
        /// 自律走行処理 定期更新(100ms)
        /// </summary>
        /// <param name="bRunAutonomous"></param>
        /// <param name="bMoveBaseCtrl"></param>
        /// <param name="SpeedKmh"></param>
        /// <returns></returns>
        public bool AutonomousProc(bool bRunAutonomous, bool bMoveBaseCtrl, double SpeedKmh)
        {
            // 自立走行に切り替わった瞬間か?
            bool trgRunAutonomous = (bRunAutonomousOld != bRunAutonomous && bRunAutonomous) ? true : false;

            UpdateCnt++;

            // すべてのルートを回りゴールした。
            if (goalFlg)
            {
                CarCtrl.nowAccValue    = 0.0;
                CarCtrl.nowHandleValue = 0.0f;
                // 停止
                CarCtrl.SetCommandAC(0.0, 0.0);

                // スマイル
                CarCtrl.SetHeadMarkLED(LEDControl.LED_PATTERN.Smile);

                return(goalFlg);
            }


            // 現在座標更新
            LocSys.RTS.SetNowPostion(LocSys.GetResultLocationX(),
                                     LocSys.GetResultLocationY(),
                                     LocSys.GetResultAngle());

            // チェックポイント送信
            {
                // チェックポイントをROSへ指示(bServer接続時も配信)
                if (LocSys.RTS.TrgCheckPoint() || trg_bServerConnect || trgRunAutonomous)
                {
                    Vector3 checkPnt = LocSys.RTS.GetCheckPointToWayPoint();// LocSys.RTS.getNowCheckPoint();
                    CarCtrl.SetCommandAG(checkPnt.x, checkPnt.y, checkPnt.z);
                }

                // 再スタート時
                if (trgRunAutonomous)
                {
                    //  0.0を一度送信
                    ModeCtrl.SetActionMode(ModeControl.ActionMode.CheckPoint);
                    CarCtrl.SetCommandAC(0.0, 0.0);
                    CarCtrl.nowAccValue    = 0.0;
                    CarCtrl.nowHandleValue = 0.0;
                    noFowrdCnt             = 0;
                    noPowerTrainCnt        = 0;
                }
            }

            // LED指示
            LedUpdate(bRunAutonomous);

            // モード更新
            ModeCtrl.Update(LocSys.GetResultDistance_mm());

            // ルート計算
            LocSys.RTS.CalcRooting(bRunAutonomous);

            if (bRunAutonomous)
            {
                // 走行指示出力

                /*
                 * // ROSの回転角度から、Benzハンドル角度の上限に合わせる
                 * double angLimit = (CarCtrl.hwMVBS_Ang * 180.0 / Math.PI);
                 * if (angLimit > 30.0) angLimit = 30.0;
                 * if (angLimit < -30.0) angLimit = -30.0;
                 *
                 *
                 * double moveAng = -(angLimit / 30.0);//-CarCtrl.hwMVBS_Ang;// * 0.3;
                 */
                double moveAng = CarCtrl.hwMVBS_Ang * 2.0;

                if (ModeCtrl.GetActionMode() == ModeControl.ActionMode.CheckPoint)
                {
                    // モード:チェックポイント目指す

                    if (bMoveBaseCtrl)
                    {
                        // move_baseコントロール
                        if (CarCtrl.hwMVBS_X > 0.0)
                        {
                            // move_baseから前進指示の場合
                            double speedRate = CarCtrl.hwMVBS_X;

                            // ハンドルで曲がるときは、速度を下げる
                            if (Math.Abs(moveAng) > 0.25)
                            {
                                speedRate *= 0.75;
                            }

                            CarCtrl.CalcHandleAccelControl(moveAng, CarCtrl.CalcAccelFromSpeed(SpeedKmh * speedRate, true));
                            //CarCtrl.SendCalcHandleAccelControl(moveAng, getAccelValue()*0.5);
                            ModeCtrl.TmpCnt = 0;
                        }
                        else
                        {
                            // move_baseから前進指示なし
                            ModeCtrl.TmpCnt++;
                            // 0.5秒
                            if (ModeCtrl.TmpCnt > 5)
                            {
                                ModeCtrl.SetActionMode(ModeControl.ActionMode.EmergencyStop);
                            }
                        }

                        // ACコマンド送信
                        CarCtrl.SetCommandAC(CarCtrl.nowHandleValue, CarCtrl.nowAccValue);
                    }
                    else
                    {
                        // VR コントロール
                        // ルートにそったハンドル、アクセル値を取得
                        double handleTgt = LocSys.RTS.GetHandleValue();
                        //double accTgt = LocSys.RTS.GetAccelValue();

                        double speedRate = 1.0;

                        // ハンドルで曲がるときは、速度を下げる
                        if (Math.Abs(handleTgt) > 0.25)
                        {
                            speedRate = 0.75;
                        }

                        CarCtrl.CalcHandleAccelControl(handleTgt, CarCtrl.CalcAccelFromSpeed(SpeedKmh * speedRate, true));

                        // ACコマンド送信
                        CarCtrl.SetCommandAC(CarCtrl.nowHandleValue, CarCtrl.nowAccValue);
                    }

                    // 共通処理

                    // 動輪の状態確認
                    if (CarCtrl.sendAccelValue >= 0.1)
                    {
                        // 動力出力指示にかかわらず、(速度50mm/s以下)
                        if (CarCtrl.nowSpeedMmSec <= 50.0)
                        {
                            // スタック(前進不能)カウンタ
                            noFowrdCnt++;
                            if (noFowrdCnt > 1000)
                            {
                                // バックで脱出を試みる
                                ModeCtrl.SetActionMode(ModeControl.ActionMode.MoveBack);
                                CarCtrl.nowAccValue = 0.0;
                                noFowrdCnt          = 0;
                            }

                            // 動力出力指示にかかわらずほぼ静止(速度10mm/s以下)
                            if (CarCtrl.nowSpeedMmSec <= 10.0)
                            {
                                // 動力カット状態カウンタ
                                noPowerTrainCnt++;

                                // 10秒以上経過
                                if (noPowerTrainCnt > 100)
                                {
                                    // 出力0%から再スタート
                                    CarCtrl.nowAccValue = 0.0;
                                    noPowerTrainCnt     = 0;
                                }
                            }
                        }
                        else
                        {
                            // 指示どおり走行している状態
                            noPowerTrainCnt = 0;
                            noFowrdCnt      = 0;
                        }
                    }
                    else
                    {
                        // 指示通り静止している状態
                    }
                }
                else if (ModeCtrl.GetActionMode() == ModeControl.ActionMode.EmergencyStop)
                {
                    if (ModeCtrl.GetActionCount() < 5)
                    {
                        // 徐行
                        CarCtrl.nowAccValue = 0.1;
                        CarCtrl.CalcHandleAccelControl(moveAng, CarCtrl.nowAccValue);
                    }
                    else
                    {
                        // move_baseから停止状態
                        //double speedRate = CarCtrl.hwMVBS_X;
                        //speedRate *= 0.75;

                        if (CarCtrl.hwMVBS_X > 0.0)
                        {
                            // 徐行解除
                            ModeCtrl.SetActionMode(ModeControl.ActionMode.CheckPoint);
                        }
                        else
                        {
                            ModeCtrl.TmpCnt++;

                            // その場、回転
                            if (Math.Abs(CarCtrl.hwMVBS_Ang) >= 0.01)
                            {
                                // 減速 [0.5km/h]
                                //CarCtrl.CalcHandleAccelControl(0.0, 0.0);
                                CarCtrl.CalcHandleAccelControl(moveAng, CarCtrl.CalcAccelFromSpeed(0.25, true));

                                if (ModeCtrl.TmpCnt > 20)
                                {
                                    // Back モード変更
                                    ModeCtrl.SetActionMode(ModeControl.ActionMode.MoveBack);
                                    CarCtrl.nowAccValue = 0.0;
                                }
                            }
                            else
                            {
                                // 停止
                                if (ModeCtrl.TmpCnt > 20)
                                {
                                    ModeCtrl.SetActionMode(ModeControl.ActionMode.EmergencyStop);
                                }
                            }
                        }
                    }

                    // ACコマンド送信
                    CarCtrl.SetCommandAC(CarCtrl.nowHandleValue, CarCtrl.nowAccValue);
                }
                else if (ModeCtrl.GetActionMode() == ModeControl.ActionMode.StackStop)
                {
                    // 完全停止
                    if (ModeCtrl.GetModePassSeconds() > 8)
                    {
                        ModeCtrl.SetActionMode(ModeControl.ActionMode.EmergencyStop);
                    }
                }
                else if (ModeCtrl.GetActionMode() == ModeControl.ActionMode.MoveBack)
                {
                    // モード:バック動作
                    if (ModeCtrl.GetActionCount() == 0)
                    {
                        // 逆ハンドル設定
                        if (Math.Abs(CarCtrl.nowTargetHandle) > 0.1)
                        {
                            backHandle = -CarCtrl.nowTargetHandle;
                        }
                        else
                        {
                            backHandle = -LocSys.RTS.GetHandleValue();
                        }
                    }

                    if (ModeCtrl.GetActionCount() < 5)
                    {
                        // スピコンブレーキ解除
                        CarCtrl.SetCommandAC(0.0, 0.0);
                    }
                    else
                    {
                        // 400mm バック
                        //if (ModeCtrl.GetModePassSeconds() > 3)
                        if (ModeCtrl.PassDistanceMm() > 400.0)
                        {
                            // 復旧
                            ModeCtrl.SetActionMode(ModeControl.ActionMode.CheckPoint);
                            CarCtrl.nowAccValue = 0.0;

                            // チェックポイント再送
                            {
                                Vector3 checkPnt = LocSys.RTS.GetCheckPointToWayPoint();
                                CarCtrl.SetCommandAG(checkPnt.x, checkPnt.y, checkPnt.z);
                            }
                        }
                        else
                        {
                            // ハンドル維持して、バック
                            CarCtrl.CalcHandleAccelControl(backHandle, CarCtrl.CalcAccelFromSpeed(SpeedKmh * 0.5, false));
                        }

                        // ACコマンド送信
                        CarCtrl.SetCommandAC(CarCtrl.nowHandleValue, CarCtrl.nowAccValue);
                    }
                }
                else
                {
                    // モード:未設定
                    ModeCtrl.SetActionMode(ModeControl.ActionMode.CheckPoint);
                }
            }
            else
            {
                // 走行指示出力しない
                CarCtrl.nowAccValue    = 0.0;
                CarCtrl.nowHandleValue = 0.0f;

                ModeCtrl.SetActionMode(ModeControl.ActionMode.CheckPoint);
            }

            // 接続トリガ取得
            trg_bServerConnect = false;
            if (!bServerConnectFlg && CarCtrl.TCP_IsConnected())
            {
                trg_bServerConnect = true;
            }

            bServerConnectFlg = CarCtrl.TCP_IsConnected();

            bRunAutonomousOld = bRunAutonomous;

            // ゴール状態取得
            goalFlg = LocSys.RTS.GetGoalStatus();

            return(goalFlg);
        }