//Initialization
    private void Start()
    {
        SceneTransi.Instance.Transi(false, null);

        currentStatus = e_status.Default;
        DontDestroyOnLoad(this);
        Connect();
    }
 /// <summary>
 /// To enable and proceed the calculation of moving toward a target
 /// </summary>
 /// <param name="x">The x of the target</param>
 /// <param name="y">The y of the target</param>
 /// <param name="theta">The bearings of the target</param>
 public static void NewTarget(Single x, Single y, Single theta, Single range)
 {
     target.X = x;
     target.Y = y;
     target.Theta = theta;
     target_range = range;
     status = e_status.HasTask;
     StopVehicle = false;
 }
        private static void MainLoop()
        {
            Single[] k = new Single[2] { 0.85f, 0.4f };

            Single diff_dist;
            Single diff_angle;
            Single tmpSingle1, tmpSingle2;
            Single Vcross;
            double deviation, deviation_old, d_deviation;
            double a, b;
            double tmpDouble1, tmpDouble2;
            int tmpInt;
            s_position Pose_old;
            s_position Vt;
            s_position Vr;
            short back_count = 0;
            short lock_count = 0;
            short hit_count = 0;
            short mark_count = 0;

            status = e_status.None;
            Pose_old.X = Pose.X;
            Pose_old.Y = Pose.Y;
            deviation = 0;
            deviation_old = 0;
            while (true)
            {

                hpcounter1.Start();

                #region Check status
                if (Vehicle.Bumper == 0xFF)
                {
                    hit_count++;
                    back_count = 20;
                }

                ob.save_sensor_reading(Vehicle.sonic);
                //if (ob.HasObstacle) status = status | e_status.HasObstacle;
                //else status = status & e_status.NoObstacle;
                #endregion

                #region Mode 1 : Force stop
                if (StopVehicle) goto Wait;
                #endregion

                #region Mode 2 : Move forward
                if(PureMove)
                {
                    if(back_count>0)
                    {
                        back_count--;
                        hit_count = 0;
                        speed = -30;
                        turn = 0;
                    }
                    else if(ob.HasObstacle)
                    {
                        ob.avoid(turn,0);
                        speed = (short)ob.OutSpeed;
                        turn = (short)ob.OutTurn;
                    }
                    else
                    {
                        speed = 60;
                        turn = 0;
                    }
                    if (ControlEvent != null) ControlEvent(null, EventArgs.Empty);
                    goto Wait;
                }
                #endregion

                #region Mode 3 : Move to target
                if (status == e_status.HasTask)
                {
                    #region Get a new task, need to initial
                    hit_count = 0;
                    back_count = 0;
                    MakeTurn(target.Theta);
                    MakeTurn(target.Theta);
                    ForwardOnly(1);
                    status = status | e_status.Initialized;
                    #endregion
                }
                if ((status & e_status.Moving) >0)
                {
                    #region diff_dist, diff_angle and check arrival
                    // calculate distance difference and check if arrived to the target
                    diff_dist = (Single)Math.Sqrt((target.X - Pose.X) * (target.X - Pose.X) + (target.Y - Pose.Y) * (target.Y - Pose.Y));
                    if (diff_dist < target_range) status = status | e_status.Arrived;

                    // calculate angle difference
                    diff_angle = (Single)(Math.Atan2((target.Y - Pose.Y), (target.X - Pose.X)) * 180f / 3.14f) - Pose.Theta;
                    if (diff_angle > 180) diff_angle = diff_angle - 360;
                    else if (diff_angle < -180) diff_angle = diff_angle + 360;
                    #endregion

                    if ((status & e_status.Arrived)>0)
                    {
                        speed = 0;
                        turn = 0;
                        status = status & e_status.NoMoving;
                    }
                    else if (back_count > 0)
                    {
                        back_count--;
                        if (hit_count == 1)
                        {
                            if (back_count == 0)
                            {
                                hit_count++;
                            }
                            else
                            {
                                speed = -35;
                                turn = 0;
                            }
                        }
                        else
                        {
                            if (back_count == 1)
                            {
                                if (diff_angle >= 0) MakeTurn(Pose.Theta + 90);
                                else MakeTurn(Pose.Theta - 90);
                            }
                            else if (back_count == 0)
                            {
                                ForwardOnly(12);
                                hit_count = 0;
                            }
                            else
                            {
                                speed = -35;
                                turn = 0;
                            }
                        }
                        Pose_old.X = Pose.X;
                        Pose_old.Y = Pose.Y;
                    }
                    else if (ob.HasObstacle)
                    {
                        lock_count = 50;
                        ob.avoid(turn,diff_angle);
                        speed = (short)ob.OutSpeed;
                        turn = (short)ob.OutTurn;
                        Pose_old.X = Pose.X;
                        Pose_old.Y = Pose.Y;
                    }
                    else
                    {
                        if (lock_count > 0) lock_count--;

                        #region determine the speed of the vehicle (for reference)
                        if (diff_dist < 150)    // if pretty close to the target
                        {
                            speed = (short)(40 + diff_dist * (max_speed - 40) / 150f);
                            if(speed<15) speed = 15;
                            max_turn = 100;
                        }
                        else                        // ordinary situation
                        {
                            speed = max_speed;
                        }
                        #endregion

                        if (lock_count == 0 && diff_dist < 150 && (diff_angle > 30 || diff_angle < -30))
                        {
                            #region if need to calibrate the bearings
                            Thread.Sleep(100);
                            MakeTurn((Single)(Math.Atan2((target.Y - Pose.Y), (target.X - Pose.X)) * 180f / 3.14f));
                            Pose_old.X = Pose.X;
                            Pose_old.Y = Pose.Y;
                            #endregion
                        }
                        else
                        {
                            #region determine the turn of the vehicle
                            tmpSingle1 = (Single)Math.Sqrt((Pose.X - Pose_old.X) * (Pose.X - Pose_old.X) + (Pose.Y - Pose_old.Y) * (Pose.Y - Pose_old.Y));
                            if (tmpSingle1 < 5)
                            {
                                // distance is too short, keep going but reduce turn angle
                                tmpSingle2 = turn * 0.8f;
                                turn = (short)tmpSingle2;
                            }
                            else
                            {
                                // calculate the cross of the two vectors
                                Vr.X = Pose.X - Pose_old.X;
                                Vr.Y = Pose.Y - Pose_old.Y;
                                Vt.X = target.X - Pose.X;
                                Vt.Y = target.Y - Pose.Y;
                                Vcross = Vr.X * Vt.Y - Vr.Y * Vt.X;

                                // calculate deviation between the vehicle and the given path
                                if ((target.X - Pose_old.X) > -1 && (target.X - Pose_old.X) < 1)
                                {
                                    a = 0;
                                    b = target.Y;
                                }
                                else
                                {
                                    a = (target.Y - Pose_old.Y) / (target.X - Pose_old.X);
                                    b = (target.Y * Pose_old.X - Pose_old.Y * target.X) / (Pose_old.X - target.X);
                                }
                                deviation = Math.Abs(a * Pose.X - Pose.Y + b) / Math.Sqrt(a * a + 1);
                                if (deviation > 20) deviation = 20;
                                else if (deviation < -20) deviation = -20;

                                // calculate compensation
                                d_deviation = deviation - deviation_old;
                                tmpDouble2 = deviation * k[0] + d_deviation * k[1];
                                if (Vcross < 0) tmpDouble2 = tmpDouble2 * -1;
                                //if (Vcross < 0 && tmpDouble2 > 5) turn = -50;
                                //else if (Vcross > 0 && tmpDouble2 > 5) turn = 50;
                                //else turn = 0;

                                // calculate turn
                                turn = (short)(turn + tmpDouble2);
                                if (turn > max_turn) turn = (short)max_turn;
                                else if (turn < max_turn * -1) turn = (short)(max_turn * -1);

                                OutStr = a.ToString("f2") + " , " + b.ToString("f2") + " , " + deviation.ToString("f2") + " , " + tmpDouble2.ToString("f2") + " , " + turn.ToString();
                                deviation_old = deviation;
                                if (mark_count >= 3)
                                {
                                    mark_count = 0;
                                    Pose_old.X = Pose.X;
                                    Pose_old.Y = Pose.Y;
                                }
                                else mark_count++;
                            }
                            #endregion
                        }

                    }
                    if (ControlEvent != null) ControlEvent(null, EventArgs.Empty);
                    goto Wait;

                }
                #endregion

            Wait:
                hpcounter1.Stop();
                tmpInt = (int)(hpcounter1.Duration * 1000f);
                if (tmpInt < 90)
                {
                    Thread.Sleep(90 - tmpInt);
                }

            }
        }
    //Loop
    void FixedUpdate()
    {
        foreach (Message m in messages)
        {
            #region Join/Left Room
            if (m.Type == "PlayerJoined")
            {
                if (!teamAttributed)
                {
                    team           = (e_teams)m.GetInt(0);
                    teamAttributed = true;
                }
                if (m.GetInt(0) == 2)
                {
                    if (currentStatus == e_status.Default)
                    {
                        GetComponent <SelectionInputs>().StartSelection(team);
                        currentStatus = e_status.InSelection;
                    }
                }
            }

            else if (m.Type == "PlayerLeft")
            {
                if (currentStatus == e_status.InSelection)
                {
                    DisconnectMe();
                }
                else if (currentStatus == e_status.InGame)
                {
                    gameplayManager.GameEnd();
                    currentStatus = e_status.GameEnded;
                }
            }

            else if (m.Type == "FullRoom")
            {
                ListRoomsJoin(roomInfos.ToArray());
            }
            #endregion

            #region Initialization Checks
            else if (m.Type == "TeamValidated")
            {
                for (int i = 0; i < 6; i++)
                {
                    heroes[i] = m.GetInt((uint)i);
                }

                SceneTransi.ToExecute exe = LoadGameplay;
                SceneTransi.Instance.Transi(true, exe);
            }

            else if (m.Type == "SceneLoaded")
            {
                gameplayManager = FindObjectOfType <GameplayManager>();

                gameplayManager.Init(this, team, heroes);
                gameplayManager.OnEnnemyTurn += EnnemyTurn;

                SceneTransi.Instance.Transi(false, null);

                Destroy(GetComponent <SelectionInputs>());
                currentStatus = e_status.InGame;
            }

            else if (m.Type == "PlacementValidated")
            {
                gameplayManager.BoardManager.PlacementValidated();
            }

            else if (m.Type == "GameStart")
            {
                gameplayManager.GameStart();
            }
            #endregion

            #region In Game
            else if (m.Type == "MoveHeroPiece")
            {
                int index = -1;
                index = m.GetInt(0);
                Vector2Int desti   = new Vector2Int(m.GetInt(1), m.GetInt(2));
                bool       useMove = m.GetBoolean(3);

                gameplayManager.BoardManager.MoveHeroPiece(index, desti, useMove);
            }

            else if (m.Type == "ModifyStatHeroPiece")
            {
                int index = -1;
                index = m.GetInt(0);
                e_stats key      = (e_stats)m.GetInt(1);
                int     value    = m.GetInt(2);
                int     duration = m.GetInt(3);
                int     tick     = m.GetInt(4);

                gameplayManager.BoardManager.ModifyStatHeroPiece(index, key, value, duration, tick);
            }

            else if (m.Type == "YourTurn")
            {
                gameplayManager.YourTurn();
            }

            else if (m.Type == "Eliminated")
            {
                gameplayManager.Eliminated((e_teams)m.GetInt(0));

                if (m.GetInt(1) <= 1)
                {
                    gameplayManager.GameEnd();
                    currentStatus = e_status.GameEnded;
                }
            }
            #endregion
        }

        messages.Clear();
    }
示例#5
0
 /// <summary>
 /// To enable and proceed the calculation of moving toward a target
 /// </summary>
 /// <param name="x">The x of the target</param>
 /// <param name="y">The y of the target</param>
 /// <param name="theta">The bearings of the target</param>
 public static bool NewTask(struct_PointF[] task,int numbers)
 {
     if (numbers >= 1)
     {
         target = new struct_PointF[numbers + 1];
         for (int i = 0; i <= numbers; i++)
         {
             target[i] = task[i];
         }
             //Array.Copy(task, target, numbers);
         TargetTotal = numbers;
         TargetNow = 1;
         status = e_status.HasTask;
         PauseVehicle = false;
         if (TargetTotal == 1) range = tg_range;
         else range = wp_range;
         return true;
     }
     else return false;
 }
示例#6
0
 public static void Abort()
 {
     speed = 0;
     turn = 0;
     PauseVehicle = true;
     status = e_status.Finish;
 }
示例#7
0
        private static void MainLoop()
        {
            Single[] k = new Single[2] { 0.8f, 1f };

            Single diff_dist;
            Single diff_angle;
            Single target_angle;
            Single robot_angle;
            Single tmpSingle1, tmpSingle2;
            Single total_dist=1;
            double Vcross, Vcross_old, d_Vcross;
            double Scross;
            double[] Vdot=new double[3];
            double deviation, deviation_old, d_deviation;
            double d_origin_path, d_current_path, d_gain;

            double tmpDouble1;
            double a, b;
            int tmpInt;
            struct_PointF Pose_old;
            struct_PointF Vt;
            struct_PointF Vr;
            short back_count = 0;
            short lock_count = 0;
            short hit_count = 0;

            status = e_status.None;
            Pose_old.X = Pose.X;
            Pose_old.Y = Pose.Y;
            deviation = 0;
            deviation_old = 0;
            Vcross_old = 0;
            while (true)
            {
                OutStr = "";
                hpcounter1.Start();

                #region Check status
                if (Vehicle.Bumper == 0xFF)
                {
                    hit_count++;
                    back_count = 20;
                }

                ob.save_sensor_reading(Vehicle.sonic);
                //if (ob.HasObstacle) status = status | e_status.HasObstacle;
                //else status = status & e_status.NoObstacle;
                #endregion

                #region Mode 1 : Force stop
                if (PauseVehicle) goto Wait;
                #endregion

                #region Mode 2 : Move forward
                if(PureMove)
                {
                    status = e_status.Moving;
                    if(back_count>0)
                    {
                        back_count--;
                        hit_count = 0;
                        speed = -30;
                        turn = 0;
                    }
                    else if(ob.Escaped)
                    {
                        speed = 80;
                        turn = 0;
                    }
                    else if(ob.HasObstacle)
                    {
                        ob.avoid(turn);
                        speed = (short)ob.OutSpeed;
                        turn = (short)ob.OutTurn;
                    }
                    else
                    {
                        speed = 80;
                        turn = 0;
                    }
                    if (ControlEvent != null) ControlEvent(null, EventArgs.Empty);
                    goto Wait;
                }
                #endregion

                #region Mode 3 : Move to target
                if (status == e_status.HasTask)
                {
                    #region Get a new task, need to initial
                    hit_count = 0;
                    back_count = 0;
                    total_dist=(Single)Math.Sqrt((target[TargetNow].X - target[TargetNow-1].X) * (target[TargetNow].X - target[TargetNow-1].X) + (target[TargetNow].Y - target[TargetNow-1].Y) * (target[TargetNow].Y - target[TargetNow-1].Y));
                    status = status | e_status.Initialized;
                    MakeTurn(target[TargetNow].Theta);
                    MakeTurn(target[TargetNow].Theta);
                    ForwardOnly(1);
                    #endregion
                }
                if ((status & e_status.Moving) >0)
                {
                    #region diff_dist, diff_angle and check arrival
                    // calculate distance difference
                    diff_dist = (Single)Math.Sqrt((target[TargetNow].X - Pose.X) * (target[TargetNow].X - Pose.X) + (target[TargetNow].Y - Pose.Y) * (target[TargetNow].Y - Pose.Y));

                    // calculate angle difference
                    target_angle = (Single)(Math.Atan2((target[TargetNow].Y - Pose.Y), (target[TargetNow].X - Pose.X)) * 180f / 3.14f);
                    robot_angle = (Single)(Math.Atan2((Pose.Y - Pose_old.Y), (Pose.X - Pose_old.X)) * 180f / 3.14f);
                    diff_angle = target_angle - Pose.Theta;
                    if (diff_angle > 180) diff_angle = diff_angle - 360;
                    else if (diff_angle < -180) diff_angle = diff_angle + 360;

                    // check if arrived to the target
                    if (diff_dist < range)
                    {
                        if (TargetNow == TargetTotal) status = status | e_status.Arrived;
                        else
                        {
                            deviation = Dot2Line(target[TargetNow].X, target[TargetNow].Y, target[TargetNow + 1].X, target[TargetNow + 1].Y, Pose.X, Pose.Y);
                            if (deviation < 30) status = status | e_status.Arrived;
                        }
                    }

                    #endregion

                    if ((status & e_status.Arrived)>0)
                    {
                        #region actions while arrived

                        if (TargetNow == TargetTotal)
                        {
                            speed = 0;
                            turn = 0;
                            status = e_status.Finish;
                        }
                        else
                        {
                            status = e_status.Moving;
                            TargetNow++;
                            if (TargetNow == TargetTotal) range = tg_range;
                            else range = wp_range;
                            total_dist=(Single)Math.Sqrt((target[TargetNow].X - target[TargetNow-1].X) * (target[TargetNow].X - target[TargetNow-1].X) + (target[TargetNow].Y - target[TargetNow-1].Y) * (target[TargetNow].Y - target[TargetNow-1].Y));
                            MakeTurn2(target[TargetNow].Theta);
                        }
                        #endregion
                    }
                    else if (back_count > 0)
                    {
                        #region perform moving backward because has hit something
                        back_count--;
                        if (hit_count == 1)
                        {
                            if (back_count == 0)
                            {
                                hit_count++;
                            }
                            else
                            {
                                speed = -40;
                                turn = 0;
                            }
                        }
                        else
                        {
                            if (back_count == 1)
                            {
                                if (diff_angle >= 0) MakeTurn(Pose.Theta + 45);
                                else MakeTurn(Pose.Theta - 45);
                            }
                            else if (back_count == 0)
                            {
                                ForwardOnly(8);
                                hit_count = 0;
                            }
                            else
                            {
                                speed = -35;
                                turn = 0;
                            }
                        }
                        Pose_old.X = Pose.X;
                        Pose_old.Y = Pose.Y;
                        #endregion
                    }
                    else if(ob.Escaped)
                    {
                        speed = (short)(0.5 * max_speed);
                        turn = 0;
                    }
                    else if (ob.HasObstacle)
                    {
                        lock_count = 50;
                        ob.avoid(turn);
                        speed = (short)ob.OutSpeed;
                        turn = (short)ob.OutTurn;
                        Pose_old.X = Pose.X;
                        Pose_old.Y = Pose.Y;
                        OutStr = "avoiding";
                    }
                    else if(ob.InCorridor)
                    {
                        ob.KeepStraight(turn);
                        turn = (short)ob.OutTurn;
                        Pose_old.X = Pose.X;
                        Pose_old.Y = Pose.Y;
                        OutStr = ob.OutStr+","+turn.ToString();
                    }
                    else
                    {
                        if (lock_count > 0) lock_count--;

                        #region determine the speed of the vehicle (for reference)
                        if (diff_dist < 200)    // if pretty close to the target
                        {
                            speed = (short)(40 + diff_dist * (max_speed - 40) / 200f);
                            if(speed < 15) speed = 15;
                            max_turn = 90;

                            if (TargetNow == TargetTotal)
                            {
                                if (lock_count == 0 && (diff_angle > 30 || diff_angle < -30))
                                {
                                    Thread.Sleep(100);
                                    MakeTurn((Single)(Math.Atan2((target[TargetTotal].Y - Pose.Y), (target[TargetTotal].X - Pose.X)) * 180f / 3.14f));
                                    Pose_old.X = Pose.X;
                                    Pose_old.Y = Pose.Y;
                                }
                            }
                        }
                        else                        // ordinary situation
                        {
                            speed = max_speed;
                            max_turn = 35;
                        }
                        #endregion

                        #region determine the turn of the vehicle
                        tmpSingle1 = (Single)Math.Sqrt((Pose.X - Pose_old.X) * (Pose.X - Pose_old.X) + (Pose.Y - Pose_old.Y) * (Pose.Y - Pose_old.Y));
                        if (tmpSingle1 < 5)
                        {
                            // distance is too short, keep going but reduce turn angle
                            tmpSingle2 = turn * 0.8f;
                            turn = (short)tmpSingle2;
                        }
                        else
                        {
                            // calculate deviation between the vehicle and the given path
                            // calculate the cross of the two vectors
                            Vr.X = Pose.X - target[TargetNow - 1].X;
                            Vr.Y = Pose.Y - target[TargetNow - 1].Y;
                            Vt.X = target[TargetNow].X - target[TargetNow - 1].X;
                            Vt.Y = target[TargetNow].Y - target[TargetNow - 1].Y;
                            Vcross = Vr.X * Vt.Y - Vr.Y * Vt.X;
                            if ((target[TargetNow].X - target[TargetNow - 1].X) > -5 && (target[TargetNow].X - target[TargetNow-1].X) < 5)
                            {
                                deviation = Math.Abs(Pose.X - target[TargetNow].X);
                            }
                            else
                            {
                                a = (target[TargetNow].Y - target[TargetNow - 1].Y) / (target[TargetNow-1].X - target[TargetNow].X);
                                deviation = Math.Abs(a * (Pose.X - target[TargetNow - 1].X) + (Pose.Y - target[TargetNow - 1].Y)) / Math.Sqrt(a * a + 1);
                            }
                            if (Vcross < 0) deviation = 0f - deviation;
                            d_deviation = deviation - deviation_old;
                            //OutStr = Pose.X.ToString()+","+ target[TargetNow - 1].X.ToString()+","+ deviation.ToString("f1");
                            d_origin_path = deviation * k[0] + d_deviation * k[1];
                            deviation_old = deviation;

                            // calculate deviation between the vehicle and the current path
                            // calculate the cross of the two vectors
                            Vr.X = Pose.X - Pose_old.X;
                            Vr.Y = Pose.Y - Pose_old.Y;
                            Vt.X = target[TargetNow].X - Pose.X;
                            Vt.Y = target[TargetNow].Y - Pose.Y;
                            Scross = Math.Sqrt(Vr.X * Vr.X + Vr.Y * Vr.Y) * Math.Sqrt(Vt.X * Vt.X + Vt.Y * Vt.Y);
                            Vcross = Vr.X * Vt.Y - Vr.Y * Vt.X;
                            Vcross = 15f*Vcross / Scross;
                            //OutStr = OutStr + "," + Vcross.ToString("f1");
                            d_Vcross = Vcross - Vcross_old;
                            d_current_path = Vcross * k[0] + d_Vcross * k[1];
                            Vcross_old = Vcross;
                            for (int i = Vdot.Length - 1; i >= 1; i--)
                            {
                                Vdot[i] = Vdot[i - 1];
                            }
                            Vdot[0] = Vr.X * Vt.X + Vr.Y * Vt.Y;

                            // combine 2 deviations
                            d_gain = 0.1 * diff_dist / total_dist;
                            //OutStr = d_origin_path.ToString("f1") + "," + d_current_path.ToString("f1") ;
                            //d_gain = 0.3;
                            tmpDouble1 = d_gain * d_origin_path + (1 - d_gain) * d_current_path;

                            if (Vdot[0] < 0 && Vdot[1] < 0)
                            {
                                Vdot[0] = 0;
                                MakeTurn2(diff_angle + Pose.Theta);
                            }
                            else
                            {
                                // calculate turn
                                //turn = (short)(tmpDouble1 + turn);
                                turn = (short)tmpDouble1;
                                if (turn > max_turn) turn = (short)max_turn;
                                else if (turn < max_turn * -1) turn = (short)(max_turn * -1);

                                if (turn > 0) turn = (short)(turn + 5);
                                else if (turn < 0) turn = (short)(turn - 5);
                            }

                            Pose_old.X = Pose.X;
                            Pose_old.Y = Pose.Y;
                        }
                        #endregion

                    }
                    if (ControlEvent != null) ControlEvent(null, EventArgs.Empty);
                    goto Wait;

                }
                #endregion

            Wait:
                hpcounter1.Stop();
                tmpInt = (int)(hpcounter1.Duration * 1000f);
                if (tmpInt < 90)
                {
                    Thread.Sleep(90 - tmpInt);
                }

            }
        }