public override void ResetEncoderLeft()
        {
            RQCommandResetEncoderLeft cmd = new RQCommandResetEncoderLeft();

            // we want to reset encoder in somewhat synchronous manner - prior to motor commands

            cmd.queue = m_commandQueue;                         // to allow re-queueing of a failed command

            m_commandQueue.Enqueue(cmd);
        }
        public override int SetMotorPowerOrSpeedRight(int powerOrSpeed)
        {
            RQCommandMotorPowerRight cmd = new RQCommandMotorPowerRight(powerOrSpeed);

            cmd.queue = m_commandPowerRightQueue;                       // to allow re-queueing of a failed command

            m_commandPowerRightQueue.Enqueue(cmd);

            return(powerOrSpeed);
        }
Beispiel #3
0
        internal override void interpretResponse(long timestamp)
        {
            whenReceivedTicks = timestamp;

            if (!isResponseSane)
            {
                string errMsg = "RQCommand: bad response to '" + toSend + "' - received '" + received[0] + "'  count=" + received.Count;
                Tracer.Error(errMsg);
                if (queue != null && m_resendCount++ < 3)
                {
                    if (queue.HasInteractionsQueued)
                    {
                        Tracer.Trace("--- fresher command in queue, not resending: " + toSend);
                    }
                    else
                    {
                        Tracer.Trace("--- resending: " + toSend);
                        queue.Enqueue(this);
                    }
                }
                return;
            }

            if (doTrace)
            {
                long ticksElapsed = 0L;

                StringBuilder strb = null;

                ticksElapsed = timestamp - whenSentTicks;
                strb         = new StringBuilder();

                for (int i = 0; i < received.Count; i++)
                {
                    strb.Append(received[i]);
                    strb.Append(" ");
                }

                Tracer.Trace("RQCommand: interpretResponse: " + received.Count + "   " + String.Format("{0:F1}", ticksElapsed / 10000.0d) + " ms  " + strb.ToString());
            }
        }
        private bool isShortQueryMode     = false;             // if true, we are replentishing query queue from the m_querySetShort. when false - from m_querySet

        public void ExecuteMain()
        {
            string statusLabel = "";

            lock (this)
            {
                if (isGrabbed)
                {
                    statusLabel = "grabbed";

                    lock (m_currentQueuePadlock)
                    {
                        if (m_currentQueue != null)
                        {
                            // still processing current query
                            if (m_currentQueue.checkForTimeout())
                            {
                                m_currentQueue = null;
                                statusLabel    = "timeout on AX2850 serial connection";
                                isUnknownState = true;
                                isInError      = true;
                            }
                        }
                    }

trySendNow:

                    if (m_currentQueue == null && !isInError)
                    {
                        // we are (almost) for sure not processing any interaction (talking to the controller).
                        // if no queue is talking, find first queue in priority list that has a processable interaction (has something to send).
                        // PriorityCurrent depends on time spent waiting grows fast with time multiplied by the queue priority factor; isProcessingInteraction==true always gets first place.
                        RQInteractionQueue queue = (from q in m_queues
                                                    where q.HasInteractionsQueued || q.isProcessingInteraction
                                                    orderby q.isProcessingInteraction descending, q.PriorityCurrent descending
                                                    select q).FirstOrDefault();

                        DateTime now = DateTime.Now;

                        if (queue != null)
                        {
                            // queue is either talking to the controller, or has something to send
                            lock (queue.padlock)
                            {
                                if (!queue.isProcessingInteraction)                                 // if queue is processing interaction, we skip this cycle and let the read handlers do their job.
                                {
                                    // done with the current interaction, get next one:
                                    if (queue.HasInteractionsQueued)
                                    {
                                        m_currentQueue = queue;                                                 // when responses are processed, this is the queue to use.
                                        if (queue is RQMotorCommandQueue)
                                        {
                                            // we cannot send motor commands more frequently than 16ms. Mark the moment when we send a command
                                            // - this is static, common for both Left and Right motor queues:
                                            RQMotorCommandQueue.lastSentTicksMotorCmd = now.Ticks;
                                            if (!isShortQueryMode)
                                            {
                                                m_queryQueue.Clear();   // prepare to be filled from m_querySetShort
                                                isShortQueryMode = (now - querySetLastSent).TotalSeconds < 1.2d;
                                                if (isShortQueryMode)
                                                {
                                                    foreach (RQQuery q in m_querySetShort)
                                                    {
                                                        q.reset();
                                                        m_queryQueue.Enqueue(q);
                                                    }
                                                }
                                                else
                                                {
                                                    foreach (RQQuery q in m_querySet)
                                                    {
                                                        q.reset();
                                                        m_queryQueue.Enqueue(q);
                                                    }
                                                    querySetLastSent = now;
                                                }
                                            }
                                            //Console.Write("M");
                                        }
                                        //else
                                        //{
                                        //    //Console.Write(isShortQueryMode ? "Q" : "L");
                                        //}
                                        queue.waitingSinceTicks = now.Ticks;
                                        m_port.WriteLine(queue.dequeueForSend());                                               // send a command or a query to controller.
                                    }
                                }
                            }
                        }
                        else
                        {
                            // all queues are empty (nothing to send), replentish the query queue.
                            // decide which query set to send - when moving fast, encoders and whiskers have priority.
                            if ((now - querySetLastSent).TotalSeconds > 1.2d || maxEncoderSpeed == 0)
                            {
                                // sending from m_querySet:

                                //Tracer.Trace("====================================================================== LONG : " + maxEncoderSpeed + "   " + prev_encoderLeftSpeed + "   " + prev_encoderRightSpeed);
                                isShortQueryMode = false;
                                foreach (RQQuery q in m_querySet)
                                {
                                    q.reset();
                                    m_queryQueue.Enqueue(q);
                                }
                                querySetLastSent = now;
                            }
                            else
                            {
                                // sending from m_querySetShort:

                                //Tracer.Trace("-------------------------------- SHORT -------------------------------------: " + maxEncoderSpeed + "   " + prev_encoderLeftSpeed + "   " + prev_encoderRightSpeed);
                                isShortQueryMode = true;
                                foreach (RQQuery q in m_querySetShort)
                                {
                                    q.reset();
                                    m_queryQueue.Enqueue(q);
                                }
                            }

                            // we now definitely have something to send, use this cycle to start the next interaction:
                            goto trySendNow;
                        }
                    }
                }
                else if (isMonitored)
                {
                    isInError   = false;
                    statusLabel = "monitored";
                }
                else if (isOnline)
                {
                    isInError   = false;
                    statusLabel = "online - receiving data";
                }
                else
                {
                    isInError   = false;
                    statusLabel = "not connected";
                }

                // trace when state changes:
                if (!statusLabel.Equals(lastStatusLabel))
                {
                    Tracer.Trace2("AX2850 : " + statusLabel);
                    lastStatusLabel        = statusLabel;
                    lastStatusLabelChanged = DateTime.Now;
                }

                if (doLogMeasuredValues)
                {
                    // create and append to a file like c:\temp\log_20120916_144334.csv for post-run motor performance analysis
                    logMeasuredValues();
                }
            }
        }