// Update is called once per frame
    void FixedUpdate()
    {
        // canvas.SetActive(false);
        // Check if to generate new random event
        if (timeCounter - lastPrint > 1)
        {
            lastPrint = timeCounter;
        }

        if (eventTimer > EVENT_INTERVAL)
        {
            eventTimer = 0;
            if (waitingEventsId.Count + ongoingEventsId.Count < shelves.Length - 1)
            {
                int   newIdx          = GenRandEvent();
                Event newWaitingEvent = eventsDict[newIdx];
                newWaitingEvent.markEvent(eventWaitingMat);
                waitingEventsId.Add(newIdx);

                totalEventCounter++;
            }
        }

        /*
         * if (cleanCounter >= CLEAN_INTERVAL && GameObject.FindGameObjectsWithTag("shatter") != null)
         * {
         *  foreach (GameObject shatterObject in GameObject.FindGameObjectsWithTag("shatter"))
         *  {
         *      // Debug.Log("cleaning + " + shatterObject);
         *      Destroy(shatterObject);
         *  }
         *  cleanCounter = 0;
         * }*/

        // while available drones, pop event
        // assign drone dst, to-do event, remove from avail, add to working drones
        // direction
        if (availableDronesId.Count > 0 && waitingEventsId.Count > 0)
        {
            int e = waitingEventsId.Next();
            int d = Utility.IS_RND_TAKEOFF ? availableDronesId.NextRnd() : availableDronesId.Next();

            Drone availableDrone = dronesDict[d];

            availableDrone.AddEvent(eventsDict[e]);
            availableDronesId.Remove(d);
            workingDronesId.Add(d);
            waitingEventsId.Remove(e);
            ongoingEventsId.Add(e);
        }

        // apply force meanwhile check collision
        foreach (int i in workingDronesId)
        {
            Vector3 force     = new Vector3();
            bool    replan    = false;
            bool    isWarning = false;
            foreach (int j in workingDronesId)
            {
                if (i == j)
                {
                    continue;
                }

                Vector3 delta = dronesDict[i].gameObjectPointer.transform.Find("pCube2").gameObject.transform.position - dronesDict[j].gameObjectPointer.transform.Find("pCube2").gameObject.transform.position;
                float   dis   = delta.magnitude;
                //Vector3 delta = dronesDict[i].curPos - dronesDict[j].curPos;
                //if (i != j && Utility.IsMoreThan(delta, CUTOFF_INTERACT))
                //{
                //    isWarning = false;
                //}
                if (dronesDict[i].gameObjectPointer.activeSelf == false || dronesDict[j].gameObjectPointer.activeSelf == false)
                {
                    continue;
                }
                if (dis < Utility.INTERACT_DIM)
                {
                    //Debug.Log("The Drone: " + i + "and " + j + "will warning");
                    // collide
                    isWarning = true;
                    if (dis < Utility.BOUND_DIM)
                    {
                        if (!(EnableSafeZoneTravel && dronesDict[i].safetyStatus == Drone.SafetyStatus.TO_SAFE_ZONE && dronesDict[j].safetyStatus == Drone.SafetyStatus.TO_SAFE_ZONE && dronesDict[i].safetyStatus == Drone.SafetyStatus.TO_NONSAFE_ZONE && dronesDict[j].safetyStatus == Drone.SafetyStatus.TO_NONSAFE_ZONE))
                        {
                            isWarning = false;
                            //Debug.Log("drone: " + i + ", " + j + " collide dealing event: " + dronesDict[i].eventId + ", " + dronesDict[j].eventId);
                            dronesDict[i].status = Drone.DroneStatus.COLLIDE;
                            dronesDict[j].status = Drone.DroneStatus.COLLIDE;
                            //dronesDict[i].gameObjectPointer.GetComponent<DroneProperties>().classPointer.CollideEffect();
                            //dronesDict[j].gameObjectPointer.GetComponent<DroneProperties>().classPointer.CollideEffect();
                        }
                        if (!dronesDict[i].isCollided && !dronesDict[j].isCollided)
                        {
                            userError++;
                            Debug.LogFormat("===== Drone {0}, Drone {1} | COLLISION =====", i, j);
                        }
                        dronesDict[j].isCollided = true;
                        dronesDict[i].isCollided = true;
                    }
                    else
                    {
                        //Debug.Log("drone " + i + ", " + j + " system plan error");
                        systemError++;
                    }
                }

                else if (Utility.IsLessThan(delta, Utility.CUTOFF_REPLAN))
                {
                    //dronesDict[i].WarningEffect(false);
                    //dronesDict[j].WarningEffect(false);

                    // replan with certain failure rate
                    if (rnd.NextDouble() < 1 - REPLAN_FAIL_RATE)
                    {
                        Debug.Log("replan for " + i);
                        force += delta;
                        replan = true;
                    }
                }
            }

            // update direction
            dronesDict[i].isWarning = (isWarning && EnableWarning);
            dronesDict[i].direction = replan ? Vector3.Normalize(force) : Vector3.Normalize(dronesDict[i].dstPos - dronesDict[i].curPos);
        }


        // check status
        // move every working drone
        for (int i = 0; i < numDrones; i++)
        {
            Drone             currDrone = dronesDict[i];
            Drone.DroneStatus status    = currDrone.status;
            if (status == Drone.DroneStatus.PARKED)
            {
                dronesDict[i].WarningRender(false);
                continue;
            }
            else if (status == Drone.DroneStatus.COLLIDE)
            {
                /*
                 * dronesDict[i].isPaused = false;
                 * dronesDict[i].WarningRender(false);
                 * dronesDict[i].curPos = dronesDict[i].parkingPos;
                 * // check the event can be added back
                 * int eid = dronesDict[i].eventId;
                 * // if (!waitingEventsId.Contains(eid) && !ongoingEventsId.Contains(eid))
                 * waitingEventsId.Add(eid);
                 *
                 * Event curEvent = eventsDict[dronesDict[i].eventId];
                 * curEvent.markEvent(eventWaitingMat);
                 *
                 * dronesDict[i].status = Drone.DroneStatus.PARKED;
                 */

                // new
                currDrone.gameObjectPointer.SetActive(false);
            }

            //else if (status == Drone.DroneStatus.TO_SHELF || status == 3)
            else if (status == Drone.DroneStatus.TO_SHELF)
            {
                if (dronesDict[i].isWarning == true)
                {
                    dronesDict[i].WarningRender(true);
                    //canvas.SetActive(true);
                }
                else
                {
                    dronesDict[i].WarningRender(false);
                }
            }

            Drone.MoveStatus moveStatus = dronesDict[i].Move();
            if (moveStatus == Drone.MoveStatus.END_TO_SHELF)  // drone status 2 --> 3
            {
                Event curEvent = eventsDict[dronesDict[i].eventId];
                curEvent.markEvent(eventIdleMat);
                ongoingEventsId.Remove(dronesDict[i].eventId);
            }

            if (dronesDict[i].status == Drone.DroneStatus.PARKED)
            {
                //dronesDict[i].HideArrow();
                workingDronesId.Remove(i);
                availableDronesId.Add(i);
                ongoingEventsId.Remove(dronesDict[i].eventId);
            }
        }

        // update counter
        timeCounter  += Time.fixedDeltaTime;
        eventTimer   += Time.fixedDeltaTime;
        cleanCounter += Time.fixedDeltaTime;

#if IS_USER_STUDY
        if (timeCounter >= EXIT_TIME)
        {
            QuitGame();
        }
#endif
    }
Example #2
0
    // Update is called once per frame
    void FixedUpdate()
    {
        if (timeCounter - lastPrint > 1)
        {
            lastPrint = timeCounter;
        }

        //Debug.LogFormat("{0} {1}", eventTimer, EVENT_INTERVAL);
        // Check if to generate new random event
        if (eventTimer > EVENT_INTERVAL)
        {
            eventTimer = 0;
            //Debug.Log("New Event Attempt");

            if (waitingEventsId.Count + ongoingEventsId.Count < shelves.Length - 1)
            {
                //  Debug.Log("New Event Created");

                int newIdx = GenRandEvent();
                waitingEventsId.Add(newIdx);
                totalEventCounter++;
            }
        }

        // try to gaurentee there are 6 crashes per minute
        if (sixtysecsCounter < 60)
        {
            sixtysecsCounter += Time.fixedDeltaTime;
        }
        else
        {
            currMinuteCrashCounter = 0;
            sixtysecsCounter       = 0;
        }

        if (availableDronesId.Count > 0 && waitingEventsId.Count > 0)
        {
            if (currMinuteCrashCounter >= 6)
            {
                Debug.Log("???????????????????????");
                PairPermutation formPermute  = new PairPermutation();
                int[]           droneIDArray = availableDronesId.getList().ToArray();
                int[]           eventIDArray = waitingEventsId.getList().ToArray();
                Debug.Log(string.Join(" ", droneIDArray));
                List <int[]> dronePermutations = PairPermutation.GetPermutation(droneIDArray);

                int  counter     = 0;
                bool hasSolution = false;
                foreach (int[] permute in dronePermutations)
                {
                    int         numOptions       = permute.Length;
                    int         size             = numOptions * numOptions;
                    List <bool> pairIntersection = new List <bool>();
                    bool        collision        = false;
                    for (int i = 0; i < numOptions - 1; i++)
                    {
                        for (int j = 0; j < numOptions - 1; j++)
                        {
                            Vector3 p1, p2, p3, p4;
                            p1        = eventsDict[eventIDArray[i]].pos;
                            p2        = dronesDict[droneIDArray[i]].hoverPos;
                            p3        = eventsDict[eventIDArray[j]].pos;
                            p4        = dronesDict[droneIDArray[j]].hoverPos;
                            collision = IsWithinCollisionBound(p1, p2, p3, p4);
                            Debug.LogFormat("Drone {0} Event {1} | Drone {2} Event{3} could crash!!!!!!!", droneIDArray[i], eventIDArray[i], droneIDArray[j], eventIDArray[j]);
                            if (collision)
                            {
                                break;
                            }
                        }
                        if (collision)
                        {
                            break;
                        }
                    }
                    if (!collision)
                    {
                        hasSolution = true;
                        break;
                    }
                    else
                    {
                        collision = false;
                        counter++;
                    }
                }
                if (hasSolution)
                {
                    int[] solution = dronePermutations[counter];
                    Utility.IS_RND_TAKEOFF = false;
                    OrderedSet <int> newAvailableDronesID = new OrderedSet <int>();
                    foreach (int item in solution)
                    {
                        newAvailableDronesID.Add(item);
                    }
                    availableDronesId = newAvailableDronesID;
                }
            }
            else
            {
                Utility.IS_RND_TAKEOFF = true;
            }
            int   e         = waitingEventsId.Next();
            int   d         = Utility.IS_RND_TAKEOFF ? availableDronesId.NextRnd() : availableDronesId.Next();
            Drone nextDrone = dronesDict[d];
            Event nextEvent = eventsDict[e];
            nextDrone.AddEvent(nextEvent);
            availableDronesId.Remove(d);
            workingDronesId.Add(d);
            waitingEventsId.Remove(e);
            ongoingEventsId.Add(e);
        }
        //if (availableDronesId.Count > 0 && waitingEventsId.Count > 0)
        //{
        //    //Debug.Log("Assigning event to drone");
        //    int e = waitingEventsId.NextRnd();
        //    //int e = waitingEventsId.Next();
        //    int d = Utility.IS_RND_TAKEOFF ? availableDronesId.NextRnd() : availableDronesId.Next();


        //    Drone avalibleDrone = dronesDict[d];

        //    avalibleDrone.AddEvent(eventsDict[e]);
        //    availableDronesId.Remove(d);
        //    workingDronesId.Add(d);
        //    waitingEventsId.Remove(e);
        //    ongoingEventsId.Add(e);
        //}

        // apply force meanwhile check collision
        foreach (int i in workingDronesId)
        {
            //Debug.Log("Drone Collision Loop 1");
            foreach (int j in workingDronesId)
            {
                if (i == j)
                {
                    continue;
                }
                //Debug.Log("Drone Collision Loop 2");
                Vector3 delta = dronesDict[i].gameObjectPointer.transform.Find("pCube2").gameObject.transform.position - dronesDict[j].gameObjectPointer.transform.Find("pCube2").gameObject.transform.position;
                float   dis   = delta.magnitude;

                //if (Utility.IsLessThan(delta, Utility.CUTOFF_INTERACT))
                if (dis < Utility.INTERACT_DIM)
                {
                    //if (Utility.IsLessThan(delta, Utility.COLLISION_BOUND))
                    if (dis < Utility.BOUND_DIM)
                    {
                        //Debug.Log("2. DroneID " + dronesDict[i].droneId + " Drone Collision");
                        if (!dronesDict[i].isCollided && !dronesDict[j].isCollided)
                        {
                            userError++;
                            currMinuteCrashCounter++;
                            Debug.LogFormat("===== Drone {0}, Drone {1} | COLLISION  =====", i, j);
                        }

                        dronesDict[i].isCollided = true;
                        dronesDict[j].isCollided = true;
                    }
                    else
                    {
                        systemError++;
                    }
                }
            }
            dronesDict[i].direction = Vector3.Normalize(dronesDict[i].dstPos - dronesDict[i].curPos);
        }


        // check status
        // move every working drone
        for (int i = 0; i < numDrones; i++)
        {
            Drone             currDrone = dronesDict[i];
            Drone.DroneStatus status    = currDrone.status;

            if (status == Drone.DroneStatus.PARKED)
            {
                continue;
            }

            Drone.MoveStatus moveStatus = currDrone.Move();


            if (moveStatus == Drone.MoveStatus.END_TO_SHELF)  // drone status 2 --> 3
            {
                ongoingEventsId.Remove(currDrone.eventId);
                if (!currDrone.isCollided)
                {
                    successEventCounter++;
                    Debug.LogFormat("Drone {0} | event {1} | COMPLETE", i, currDrone.eventId);
                }
                else
                {
                    Debug.LogFormat("Drone {0} event {1} | CRASH", i, currDrone.eventId);
                }
            }

            if (currDrone.status == Drone.DroneStatus.PARKED)
            {
                currDrone.isCollided = false;
                workingDronesId.Remove(i);
                availableDronesId.Add(i);
                ongoingEventsId.Remove(currDrone.eventId);
            }
        }
        // update counter
        timeCounter += Time.fixedDeltaTime;
        eventTimer  += Time.fixedDeltaTime;
        cleanCounter++;


#if IS_USER_STUDY
        if (SEED <= MAX_SEED)
        {
            if (timeCounter >= EXIT_TIME)
            {
                Debug.Log("====================End of a 3 minute user study=============================");
                //Debug.Log(SEED);
                ResetSim();

                ReloadScene();


                //QuitGame();
            }
        }
        else
        {
            Debug.Log("???????????????????????????");
            QuitGame();
        }
#endif
    }