Exemple #1
0
        /// <summary>
        /// Sends a command followed by command arguments to robot.
        /// </summary>
        /// <param name="command">A command to send.</param>
        /// <param name="args">An array of bytes specifying the arguments for the command.</param>
        /// <returns>An instance of SerialResponse containing the response data received from the robot.</returns>
        /// <exception cref="ApplicationException">Thrown if the serial response does not match serial command.</exception>
        private SerialResponse SendCommand(SerialCommands command, params byte[] args)
        {
            lock (this._lockCommand)
            {
                // Clear the port and response buffer.
                this._responseBufferLength = 0;
                if (Port.BytesToRead > 0)
                {
                    Port.ReadExisting();
                }

                // Send command followed by any arguments.
                Port.Write(new byte[] { (byte)command }, 0, 1);
                if (args != null && args.Length > 0)
                {
                    Port.Write(args, 0, args.Length);
                }

                // Wait to receive a complete response or until timeout.
                SerialResponse serialResponse = this.ReadResponse();

                if (serialResponse.SerialCommand != command)
                {
                    throw new ApplicationException("Serial response did not match serial command.");
                }

                return(serialResponse);
            }
        }
Exemple #2
0
        /// <summary>
        /// Captures a compressed video frame from the camera.
        /// </summary>
        /// <returns>A Bitmap.</returns>
        public Bitmap CaptureImage()
        {
            SerialResponse serialResponse = this.SendCommand(SerialCommands.GrabCompressedVideoFrame);

            if (!(serialResponse.Data is Bitmap))
            {
                throw new ApplicationException("GrabFrame request did not return a valid Image");
            }

            return(serialResponse.Data as Bitmap);
        }
Exemple #3
0
        /// <summary>
        /// View raw "Pixel Column Vector" data in "Wander Mode".
        /// </summary>
        /// <returns>An array of bytes representing 80 columns. Each column is assigned with a value
        /// of 0 to 64 that indicates the pixel position of the first non-floor pixel for that
        /// column (a value of 64 means there is no blockage).</returns>
        public byte[] Scan()
        {
            SerialResponse serialResponse = this.SendCommand(SerialCommands.Scan);

            if (!(serialResponse.Data is Byte[]))
            {
                throw new ApplicationException("Scan request did not return valid data.");
            }

            return(serialResponse.Data as Byte[]);
        }
Exemple #4
0
        /// <summary>
        /// Estimates the proximity on each side by emitting IR signals and counting the bounced bits.
        /// </summary>
        /// <returns>An instance of BounceIRResponse containing the proximity info on each side of the robot.</returns>
        public BounceIRResponse GetProximity()
        {
            SerialResponse serialResponse = this.SendCommand(SerialCommands.BounceInfraRed);

            // The response will be in form "##BounceIR - aa bb cc dd\n".
            // aa bb cc dd are bounced bit counts for front, left, back, right.

            if (!(serialResponse.Data is BounceIRResponse))
            {
                throw new ApplicationException("BounceIR request did not return a valid BounceIRResponse");
            }

            return(serialResponse.Data as BounceIRResponse);
        }
Exemple #5
0
        /// <summary>
        /// Waits for response data to fully load in the buffer and returns the response data.
        /// </summary>
        /// <remarks>
        /// By convention all commands from the host are single byte ASCII characters,
        /// and all commands receive an acknowledgment from the robot, which is either
        /// a '#' character followed by the command, or '##' for variable length responses.
        /// </remarks>
        /// <param name="command">The command for which a response is expected.</param>
        /// <returns>An instance of SerialResponse containing the response data received from the robot.</returns>
        /// <exception cref="TimeoutException">Thrown if the response data times out before being retrieved.</exception>
        /// <exception cref="ApplicationException">Thrown if the response buffer overflows.</exception>
        private SerialResponse ReadResponse()
        {
            const int msInterval = 100;
            int       waitEnd    = Environment.TickCount + this.ResponseTimeout;

            this._responseBufferLength = 0;

            // Load data into response buffer.
            while (true)
            {
                if (Port.BytesToRead > 0)
                {
                    int maxBytesToRead = Math.Min(this._responseBuffer.Length - this._responseBufferLength, Port.BytesToRead);

                    for (int lcv = 0; lcv < maxBytesToRead; lcv++)
                    {
                        // Read one byte at a time.
                        this._responseBuffer[this._responseBufferLength++] = (byte)Port.ReadByte();
                    }

                    // Parse the response data received so far.
                    SerialResponse serialResponse = this.ParseSerialResponse();
                    if (serialResponse != null)
                    {
                        return(serialResponse);
                    }

                    // Check the received packet won't overflow in the response buffer.
                    if (this._responseBufferLength == this._responseBuffer.Length)
                    {
                        throw new ApplicationException("Response buffer overflowed.");
                    }
                }

                if (Environment.TickCount > waitEnd)
                {
                    throw new TimeoutException("Response timed out");
                }

                System.Threading.Thread.Sleep(msInterval);
            }
        }