/// <summary>
        /// Add a new Periodic Task to the Scheduler
        /// </summary>
        /// <param name="thePeriodicTask">The Periodic Task to Add</param>
        public void Add(PeriodicTask thePeriodicTask)
        {
            //taskQueue.Add(thePeriodicTask.Period, thePeriodicTask);

            // Checks if another task has been already scheduled at the same time
            // long nextDueTime = thePeriodicTask.Period;
            long nextDueTime = 0;
            bool scheduled   = false;

            while (!scheduled)
            {
                if (AlreadyScheduled(nextDueTime))
                {
                    nextDueTime = nextDueTime + standardDelayWhenOverscheduled;
                }
                else
                {
                    scheduled = true;
                }
            }
            taskQueue.Add(new TaskTimingStructure(nextDueTime), thePeriodicTask);
        }
        /// <summary>
        /// The scheduler algorithm
        /// </summary>
        protected void theScheduler()
        {
            // Sleeps until first due time
            stopWatch.Reset();
            stopWatch.Start();
            // LcdConsole.WriteLine("Stopwatch started");

            if (taskQueue.Count != 0)
            {
                while (keepScheduling)
                {
                    // Gets current time task data
                    long msec               = stopWatch.ElapsedMilliseconds;
                    long dueTime            = taskQueue.Keys[0].nextDueTime;
                    long numberOfExecutions = taskQueue.Keys[0].numberOfExecutions;
                    // LcdConsole.WriteLine("Extracting data");

                    // Time to wait until next execution
                    int rest = (int)(dueTime - msec);

                    // Put this thread to sleep if the dueTime is further than 200ms
                    if (rest > 200)
                    {
                        // LcdConsole.WriteLine("Waiting asleep");
                        Thread.Sleep(rest - 200);
                    }

                    // When dueTime is closer than 200ms, this function actively waits the stopwatch
                    while (true)
                    {
                        // LcdConsole.WriteLine("Waiting awake");
                        if (stopWatch.ElapsedMilliseconds >= msec + rest)
                        {
                            break;
                        }
                    }

                    // When the stopwatch reaches the dueTime, the callBack function is invoked
                    // But before checks the the scheduler has not been stopped
                    // while waiting
                    if (keepScheduling)
                    {
                        PeriodicTask task = TaskQueue.Values[0];
                        if (withLog)
                        {
                            // Logs the execution time
                            executionLog = executionLog +
                                           stopWatch.ElapsedMilliseconds.ToString() + " " +
                                           task.Name + "\r\n";
                        }

                        // Executes the action
                        // LcdConsole.WriteLine("Launching action " + task.Name);
                        // LcdConsole.WriteLine("Sched error: " + Math.Abs(dueTime - stopWatch.ElapsedMilliseconds).ToString("F2"));
                        task.Action(robot);

                        // Determines next due time
                        // LcdConsole.WriteLine("Computes next due time");
                        long nextDueTime = (numberOfExecutions + 1) * task.Period;
                        bool slotFound   = false;

                        // Updates the due time
                        PeriodicTask updatedTask = task;
                        taskQueue.RemoveAt(0);

                        while (!slotFound)
                        {
                            // Check for task already scheduled at the same time
                            if (AlreadyScheduled(nextDueTime))
                            {
                                // If a task is already scheduled at the same time
                                // try next millisecond
                                nextDueTime = nextDueTime + standardDelayWhenOverscheduled;
                            }
                            else
                            {
                                // First task to be scheduled at this nextDueTime slot
                                slotFound = true;
                            }
                        }

                        // schedules the task
                        TaskTimingStructure key = new TaskTimingStructure(nextDueTime);
                        key.numberOfExecutions = numberOfExecutions + 1;
                        taskQueue.Add(key, task);
                    }
                }
            }
            stopWatch.Stop();
        }