Exemplo n.º 1
0
        /// <summary>
        /// Internal rotate degrees handler
        /// </summary>
        /// <param name="rotateDegrees"></param>
        /// <returns></returns>
        public virtual IEnumerator <ITask> InternalRotateDegreesHandler(drive.RotateDegrees rotateDegrees)
        {
            switch (rotateDegrees.Body.RotateDegreesStage)
            {
            case drive.DriveStage.InitialRequest:
                _state.InternalPendingDriveOperation = drive.DriveRequestOperation.RotateDegrees;
                SpawnIterator <double, double>(rotateDegrees.Body.Degrees, rotateDegrees.Body.Power, RotateUntilDegrees);
                break;

            case drive.DriveStage.Started:
                SendNotification <drive.RotateDegrees>(_subMgrPort, rotateDegrees.Body);
                break;

            case drive.DriveStage.Completed:
                _state.InternalPendingDriveOperation = drive.DriveRequestOperation.NotSpecified;
                SendNotification <drive.RotateDegrees>(_subMgrPort, rotateDegrees.Body);
                break;

            case drive.DriveStage.Canceled:
                _state.InternalPendingDriveOperation = drive.DriveRequestOperation.NotSpecified;
                SendNotification <drive.RotateDegrees>(_subMgrPort, rotateDegrees.Body);
                break;
            }

            yield break;
        }
Exemplo n.º 2
0
        public void DriveRotateHandler(diffdrive.RotateDegrees rotate)
        {
            if (this.driveEntity == null)
            {
                throw new InvalidOperationException("Simulation entity not registered with service");
            }

            if (!this.state.DriveState.IsEnabled)
            {
                rotate.ResponsePort.Post(Fault.FromException(new Exception("Drive is not enabled.")));
                LogError("RotateDegrees request to disabled drive.");
                return;
            }

            this.state.DriveState.RotateDegreesStage = rotate.Body.RotateDegreesStage;
            if (rotate.Body.RotateDegreesStage == diffdrive.DriveStage.InitialRequest)
            {
                var entityResponse = new Port <engine.OperationResult>();
                Activate(
                    Arbiter.Receive(
                        false,
                        entityResponse,
                        result =>
                {
                    // post a message to ourselves indicating that the drive distance has completed
                    var req = new diffdrive.RotateDegreesRequest(0, 0);
                    switch (result)
                    {
                    case engine.OperationResult.Error:
                        req.RotateDegreesStage = diffdrive.DriveStage.Canceled;
                        break;

                    case engine.OperationResult.Canceled:
                        req.RotateDegreesStage = diffdrive.DriveStage.Canceled;
                        break;

                    case engine.OperationResult.Completed:
                        req.RotateDegreesStage = diffdrive.DriveStage.Completed;
                        break;
                    }

                    this.drivePort.Post(new diffdrive.RotateDegrees(req));
                }));

                this.driveEntity.RotateDegrees((float)rotate.Body.Degrees, (float)rotate.Body.Power, entityResponse);

                var req2 = new diffdrive.RotateDegreesRequest(0, 0)
                {
                    RotateDegreesStage = diffdrive.DriveStage.Started
                };
                this.drivePort.Post(new diffdrive.RotateDegrees(req2));
            }
            else
            {
                SendNotification(this.subMgrPort, rotate);
            }

            rotate.ResponsePort.Post(DefaultUpdateResponseType.Instance);
        }
Exemplo n.º 3
0
 public void DriveRotateDegreesHandler(drive.RotateDegrees rotatedegrees)
 {
     this.controllerDrivePort.Post(
         new drive.RotateDegrees()
     {
         Body = rotatedegrees.Body, ResponsePort = rotatedegrees.ResponsePort
     });
 }
Exemplo n.º 4
0
        public IEnumerator <ITask> DriveRotateDegreesHandler(drive.RotateDegrees rotatedegrees)
        {
            if (!this.state.DriveState.IsEnabled)
            {
                rotatedegrees.ResponsePort.Post(soap.Fault.FromCodeSubcodeReason(
                                                    soap.FaultCodes.Receiver,
                                                    DsspFaultCodes.OperationFailed,
                                                    "Drive not enabled!"));
                yield break;
            }

            this.state.DriveState.TimeStamp = DateTime.Now;

            short pwr = (short)(board.HBridgeReverseMax +
                                ((rotatedegrees.Body.Power - GDDriveMin)
                                 * DrivePowerScale));
            short deg = (short)(this.encoderTicksPerMeter[(int)Sides.Left] * rotatedegrees.Body.Degrees);

            byte[] cmdpacket = board.CreatePacket <short, short>(board.SetRotateInPlaceString, deg, pwr);

            serialcomservice.SendAndGetRequest sg = new serialcomservice.SendAndGetRequest();
            sg.Timeout = this.state.DefaultResponsePause;
            sg.Data    = new serialcomservice.Packet(cmdpacket);

            var resultPort = this.serialCOMServicePort.SendAndGet(sg);

            yield return(resultPort.Choice());

            soap.Fault f = (soap.Fault)resultPort;
            if (f != null)
            {
                LogError(string.Format("Failed to send command: {0}", Encoding.ASCII.GetString(sg.Data.Message)));
                rotatedegrees.ResponsePort.Post(f);
                yield break;
            }

            if (this.HasFWError((serialcomservice.Packet)resultPort))
            {
                f = soap.Fault.FromCodeSubcodeReason(
                    soap.FaultCodes.Receiver,
                    DsspFaultCodes.OperationFailed,
                    "Error received from FW!");
                rotatedegrees.ResponsePort.Post(f);
                yield break;
            }

            this.state.DriveState.LeftWheel.MotorState.CurrentPower  = rotatedegrees.Body.Power;
            this.state.DriveState.RightWheel.MotorState.CurrentPower = rotatedegrees.Body.Power;
            rotatedegrees.ResponsePort.Post(DefaultUpdateResponseType.Instance);
        }
Exemplo n.º 5
0
        public IEnumerator <ITask> RotateDegreesHandler(RotateDegrees rotateDegrees)
        {
            ValidateDriveConfiguration(true);
            if (_state.DistanceBetweenWheels <= 0)
            {
                rotateDegrees.ResponsePort.Post(new Fault());
                throw new InvalidOperationException("The wheel encoders are not properly configured");
            }
            else
            {
                _state.TimeStamp = DateTime.Now;

                // send immediate response
                rotateDegrees.ResponsePort.Post(DefaultUpdateResponseType.Instance);


                // send immediate response
                rotateDegrees.ResponsePort.Post(DefaultUpdateResponseType.Instance);

                // post request to internal port.
                _internalDriveOperationsPort.Post(rotateDegrees);
            }
            yield break;
        }
Exemplo n.º 6
0
        /// <summary>
        /// Rotate the the drive (positive degrees turn counterclockwise)
        /// </summary>
        /// <param name="degrees">(positive degrees turn counterclockwise)</param>
        /// <param name="power">(-1.0 to 1.0)</param>
        IEnumerator <ITask> RotateUntilDegrees(double degrees, double power)
        {
            //reset encoders
            encoder.Reset Lreset = new encoder.Reset();
            _leftEncoderPort.Post(Lreset);
            yield return(Arbiter.Choice(Lreset.ResponsePort,
                                        delegate(DefaultUpdateResponseType response) { },
                                        delegate(Fault fault) { LogError(fault); }
                                        ));

            encoder.Reset Rreset = new encoder.Reset();
            _rightEncoderPort.Post(Rreset);
            yield return(Arbiter.Choice(Rreset.ResponsePort,
                                        delegate(DefaultUpdateResponseType response) { },
                                        delegate(Fault fault) { LogError(fault); }
                                        ));

            double arcDistance = Math.Abs(degrees) * _state.DistanceBetweenWheels * 3.14159 / 360;

            //compute tick to stop at
            int stopLeftWheelAt  = (int)Math.Round(arcDistance / (2.0 * 3.14159 * _state.LeftWheel.Radius / _state.LeftWheel.EncoderState.TicksPerRevolution));
            int stopRightWheelAt = (int)Math.Round(arcDistance / (2.0 * 3.14159 * _state.RightWheel.Radius / _state.RightWheel.EncoderState.TicksPerRevolution));

            // Subscribe to the encoders on internal ports
            encoder.EncoderOperations leftNotificationPort  = new encoder.EncoderOperations();
            encoder.EncoderOperations rightNotificationPort = new encoder.EncoderOperations();

            encoder.Subscribe op = new encoder.Subscribe();
            op.Body             = new SubscribeRequestType();
            op.NotificationPort = leftNotificationPort;
            _leftEncoderPort.Post(op);

            yield return(Arbiter.Choice(op.ResponsePort,
                                        delegate(SubscribeResponseType response)
            {
                //subscription was successful, start listening for encoder replace messages
                Activate(Arbiter.Receive <encoder.UpdateTickCount>(false, leftNotificationPort,
                                                                   delegate(encoder.UpdateTickCount update)
                {
                    StopMotorWithEncoderHandler(leftNotificationPort, update, _leftMotorPort, stopLeftWheelAt);
                }));
            },
                                        delegate(Fault fault) { LogError(fault); }
                                        ));


            encoder.Subscribe op2 = new encoder.Subscribe();
            op2.Body             = new SubscribeRequestType();
            op2.NotificationPort = rightNotificationPort;
            _leftEncoderPort.Post(op2);
            yield return(Arbiter.Choice(op2.ResponsePort,
                                        delegate(SubscribeResponseType response)
            {
                //subscription was successful, start listening for encoder replace messages
                Activate(Arbiter.Receive <encoder.UpdateTickCount>(false, rightNotificationPort,
                                                                   delegate(encoder.UpdateTickCount update)
                {
                    StopMotorWithEncoderHandler(rightNotificationPort, update, _rightMotorPort, stopRightWheelAt);
                }
                                                                   ));
            },
                                        delegate(Fault fault) { LogError(fault); }
                                        ));


            //start moving

            // start rotate operation
            _state.RotateDegreesStage = DriveStage.Started;

            RotateDegrees rotateUpdate = new RotateDegrees();

            rotateUpdate.Body.RotateDegreesStage = DriveStage.Started;
            _internalDriveOperationsPort.Post(rotateUpdate);

            PortSet <DefaultUpdateResponseType, Fault> responsePort = new PortSet <DefaultUpdateResponseType, Fault>();

            double rightPow;
            double leftPow;

            if (degrees > 0)
            {
                rightPow = power;
                leftPow  = -power;
            }
            else
            {
                rightPow = -power;
                leftPow  = power;
            }

            Motor.SetMotorPower leftPower = new Motor.SetMotorPower(leftPow);
            leftPower.ResponsePort = responsePort;
            _leftMotorPort.Post(leftPower);

            Motor.SetMotorPower rightPower = new Motor.SetMotorPower(rightPow);
            rightPower.ResponsePort = responsePort;
            _rightMotorPort.Post(rightPower);

            Activate(Arbiter.MultipleItemReceive <DefaultUpdateResponseType, Fault>(responsePort, 2,
                                                                                    delegate(ICollection <DefaultUpdateResponseType> successList, ICollection <Fault> failureList)
            {
                foreach (Fault fault in failureList)
                {
                    LogError(fault);
                }
            }
                                                                                    ));

            _state.RotateDegreesStage = DriveStage.Completed;
            //complete
            rotateUpdate.Body.RotateDegreesStage = DriveStage.Completed;
            _internalDriveOperationsPort.Post(rotateUpdate);
        }
Exemplo n.º 7
0
 public IEnumerator <ITask> RotateDegreesHandler(drive.RotateDegrees rotateDegrees)
 {
     LogError("Rotate degrees is not implemented");
     yield break;
 }