public override bool[] GET_MCU_Status(RadioTelescopeAxisEnum axis)    //set
 {
     bool[] stuf = new bool[33];
     for (int i = 0; i < 32; i++)
     {
         stuf[i] = true;
     }
     return(stuf);
 }
示例#2
0
        public override bool Start_jog(RadioTelescopeAxisEnum axis, int speed, bool clockwise)
        {
            ushort adress = MCUConstants.ACTUAL_MCU_WRITE_REGISTER_START_ADDRESS, dir;

            if (clockwise)
            {
                dir = 0x0080;
            }
            else
            {
                dir = 0x0100;
            }
            //                                         reserved       msb speed            lsb speed  acc  dcc  reserved
            ushort[] data = new ushort[] { dir, 0x0003, 0x0, 0x0, (ushort)(speed >> 16), (ushort)speed, 50, 25, 0x0, 0x0 };// this is a jog comand for a single axis
            RadioTelescopeAxisEnum jogging_axies = Is_jogging();

            switch (axis)
            {
            case RadioTelescopeAxisEnum.AZIMUTH:
            {
                break;
            }

            case RadioTelescopeAxisEnum.ELEVATION:
            {
                adress = MCUConstants.ACTUAL_MCU_WRITE_REGISTER_START_ADDRESS + 10;
                break;
            }

            case RadioTelescopeAxisEnum.BOTH:
            {
                ushort[] data2 = new ushort[data.Length * 2];
                data.CopyTo(data2, 0);
                data.CopyTo(data2, data.Length);
                data = data2;
                break;
            }

            default:
            {
                throw new ArgumentException("Invalid RadioTelescopeAxisEnum value can be AZIMUTH, ELEVATION or BOTH got: " + axis);
            }
            }
            MCUModbusMaster.WriteMultipleRegisters(adress, data);
            return(true);
            //throw new NotImplementedException();
        }
示例#3
0
        /// <summary>
        /// get an array of boolens representiing the register described on pages 76 -79 of the mcu documentation
        /// does not suport RadioTelescopeAxisEnum.BOTH
        /// see <see cref="MCUConstants.MCUStatusBitsMSW"/> for description of each bit
        /// </summary>
        public override bool[] GET_MCU_Status(RadioTelescopeAxisEnum axis)
        {
            ushort start = 0;

            if (axis == RadioTelescopeAxisEnum.ELEVATION)
            {
                start = 10;
            }
            ushort[] data   = MCU.ReadMCURegisters(start, 2);
            bool[]   target = new bool[32];
            for (int i = 0; i < 16; i++)
            {
                target[i]      = ((data[0] >> i) & 1) == 1;
                target[i + 16] = ((data[1] >> i) & 1) == 1;
            }
            return(target);
        }
        /// <summary>
        /// Gets the direction that the specfied axis is moving.
        /// </summary>
        /// <param name="axis">Azimuth or elevation.</param>
        /// <returns>The direction that the specfied axis is spinning.</returns>
        public override RadioTelescopeDirectionEnum GetRadioTelescopeDirectionEnum(RadioTelescopeAxisEnum axis)
        {
            ushort[] directionData;

            switch (axis)
            {
            //Axes must be checked independently because the MCU commands for motor moves have the same value for both Az and El
            case RadioTelescopeAxisEnum.AZIMUTH:
                directionData = MCU.ReadMCURegisters(0, 1);
                if ((directionData[(int)MCUConstants.MCUOutputRegs.AZ_Status_Bist_MSW] >> (int)MCUConstants.MCUStatusBitsMSW.CCW_Motion & 0b1) == 1)
                {
                    return(RadioTelescopeDirectionEnum.CounterclockwiseOrPositive);
                }

                if ((directionData[(int)MCUConstants.MCUOutputRegs.AZ_Status_Bist_MSW] >> (int)MCUConstants.MCUStatusBitsMSW.CW_Motion & 0b1) == 1)
                {
                    return(RadioTelescopeDirectionEnum.ClockwiseOrNegative);
                }
                break;

            case RadioTelescopeAxisEnum.ELEVATION:
                //in practice, only need to check the elevation
                directionData = MCU.ReadMCURegisters(10, 1);

                if (((directionData[(int)MCUConstants.MCUOutputRegs.EL_Status_Bist_MSW - 10] >> (int)MCUConstants.MCUStatusBitsMSW.CCW_Motion) & 0b1) == 1)
                {
                    return(RadioTelescopeDirectionEnum.CounterclockwiseOrPositive);
                }

                if (((directionData[(int)MCUConstants.MCUOutputRegs.EL_Status_Bist_MSW - 10] >> (int)MCUConstants.MCUStatusBitsMSW.CW_Motion) & 0b1) == 1)
                {
                    return(RadioTelescopeDirectionEnum.ClockwiseOrNegative);
                }
                break;

            default:
                //This function can only accept a single axis (either Az or El)
                //see comment at top of function
                throw new ArgumentException();
            }

            return(RadioTelescopeDirectionEnum.None);
        }
        /// <summary>
        /// Method used to request that all of the Radio Telescope's movement comes
        /// to an immediate stop.
        ///
        /// The implementation of this functionality is on a "per-RT" basis, as
        /// in this may or may not work, it depends on if the derived
        /// AbstractRadioTelescope class has implemented it.
        /// </summary>
        public bool ExecuteMoveRelativeAzimuth(RadioTelescopeAxisEnum axis, int speed, int position)
        {
            int positionTranslationAZ = 0, positionTranslationEL = 0;

            if (axis == RadioTelescopeAxisEnum.ELEVATION)
            {
                positionTranslationEL = position;
            }
            else if (axis == RadioTelescopeAxisEnum.AZIMUTH)
            {
                positionTranslationAZ = position;
            }
            else
            {
                return(false);
            }

            return(RadioTelescope.PLCDriver.relative_move(speed, (ushort)50, positionTranslationAZ, positionTranslationEL));
            //return MinorResponseIsValid(RadioTelescope.PLCClient.RequestMessageSend(PLCCommandAndQueryTypeEnum.TRANSLATE_AZEL_POSITION, axis, speed, position));
        }
示例#6
0
 public override bool Controled_stop(RadioTelescopeAxisEnum axis, bool both)
 {
     ushort[] data = new ushort[] { 0x4, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
     if (both)
     {
         MCUModbusMaster.WriteMultipleRegisters(MCUConstants.ACTUAL_MCU_WRITE_REGISTER_START_ADDRESS, MESSAGE_CONTENTS_HOLD_MOVE);
         return(true);
     }
     else if (axis == RadioTelescopeAxisEnum.AZIMUTH)
     {
         MCUModbusMaster.WriteMultipleRegisters(MCUConstants.ACTUAL_MCU_WRITE_REGISTER_START_ADDRESS, data);
         return(true);
     }
     else if (axis == RadioTelescopeAxisEnum.ELEVATION)
     {
         MCUModbusMaster.WriteMultipleRegisters(MCUConstants.ACTUAL_MCU_WRITE_REGISTER_START_ADDRESS + 10, data);
         return(true);
     }
     return(false);
 }
示例#7
0
        /// <summary>
        /// return true if the RT has finished the previous move comand
        /// </summary>
        public bool finished_exicuting_move(RadioTelescopeAxisEnum axis)  //[7]
        {
            var Taz = RadioTelescope.PLCDriver.GET_MCU_Status(RadioTelescopeAxisEnum.AZIMUTH);
            var Tel = RadioTelescope.PLCDriver.GET_MCU_Status(RadioTelescopeAxisEnum.ELEVATION);

            bool azFin = Taz[(int)MCUConstants.MCUStatusBitsMSW.Move_Complete];
            bool elFin = Tel[(int)MCUConstants.MCUStatusBitsMSW.Move_Complete];

            if (axis == RadioTelescopeAxisEnum.BOTH)
            {
                return(elFin && azFin);
            }
            else if (axis == RadioTelescopeAxisEnum.AZIMUTH)
            {
                return(azFin);
            }
            else if (axis == RadioTelescopeAxisEnum.ELEVATION)
            {
                return(elFin);
            }
            return(false);
        }
示例#8
0
 public override RadioTelescopeDirectionEnum GetRadioTelescopeDirectionEnum(RadioTelescopeAxisEnum axis)
 {
     return(driver.GetRadioTelescopeDirectionEnum(axis));
 }
 public override bool Start_jog(RadioTelescopeAxisEnum axis, int speed, bool clockwise)
 {
     throw new NotImplementedException();
 }
 public override bool Controled_stop(RadioTelescopeAxisEnum axis, bool both)
 {
     throw new NotImplementedException();
 }
 /// <summary>
 /// Checks to see if the motors are currently moving.
 /// </summary>
 /// <param name="axis">Azimuth, elevation, or both.</param>
 /// <returns>True if moving, false if not moving.</returns>
 public abstract bool MotorsCurrentlyMoving(RadioTelescopeAxisEnum axis = RadioTelescopeAxisEnum.BOTH);
 /// <summary>
 /// get an array of boolens representiing the register described on pages 76 -79 of the mcu documentation
 /// does not suport RadioTelescopeAxisEnum.BOTH
 /// see <see cref="MCUConstants.MCUStatusBitsMSW"/> for description of each bit
 /// </summary>
 /// <param name="axis"></param>
 /// <returns></returns>
 public abstract bool[] GET_MCU_Status(RadioTelescopeAxisEnum axis);
示例#13
0
 public abstract bool Start_jog(RadioTelescopeAxisEnum axis, int speed, bool clockwise);
示例#14
0
 public override bool Controled_stop(RadioTelescopeAxisEnum axis, bool both)
 {
     return(driver.Controled_stop(axis, both));
 }
示例#15
0
 public override bool Start_jog(RadioTelescopeAxisEnum axis, int speed, bool clockwise)
 {
     return(driver.Start_jog(axis, speed, clockwise));
 }
 /// <summary>
 /// Method used to request to start jogging one of the Radio Telescope's axes
 /// at a speed, in either the clockwise or counter-clockwise direction.
 ///
 /// The implementation of this functionality is on a "per-RT" basis, as
 /// in this may or may not work, it depends on if the derived
 /// AbstractRadioTelescope class has implemented it.
 /// </summary>
 public bool StartRadioTelescopeJog(RadioTelescopeAxisEnum axis, int speed, bool clockwise)
 {
     return(RadioTelescope.PLCDriver.Start_jog(axis, speed, clockwise));
     //return MinorResponseIsValid(RadioTelescope.PLCClient.RequestMessageSend(PLCCommandAndQueryTypeEnum.START_JOG_MOVEMENT, axis, speed, clockwise));
 }
        public byte[] RequestMessageSend(PLCCommandAndQueryTypeEnum MessageType, params object[] MessageParameters)
        {
            byte[] NetOutgoingMessage =
            {
                0x13,                                                              0x0,
                PLCCommandAndQueryTypeConversionHelper.ConvertToByte(MessageType),
                0x0,                                                               0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
                0x0,                                                               0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
            };

            PLCCommandResponseExpectationEnum ResponseExpectationValue;

            switch (MessageType)
            {
            case PLCCommandAndQueryTypeEnum.TEST_CONNECTION:
            case PLCCommandAndQueryTypeEnum.GET_CURRENT_AZEL_POSITIONS:
            case PLCCommandAndQueryTypeEnum.GET_CURRENT_LIMIT_SWITCH_STATUSES:
            case PLCCommandAndQueryTypeEnum.GET_CURRENT_SAFETY_INTERLOCK_STATUS:
            {
                ResponseExpectationValue = PLCCommandResponseExpectationEnum.FULL_RESPONSE;
                break;
            }

            case PLCCommandAndQueryTypeEnum.CANCEL_ACTIVE_OBJECTIVE_AZEL_POSITION:
            case PLCCommandAndQueryTypeEnum.SHUTDOWN:
            case PLCCommandAndQueryTypeEnum.CALIBRATE:
            case PLCCommandAndQueryTypeEnum.CONTROLLED_STOP:
            case PLCCommandAndQueryTypeEnum.IMMEDIATE_STOP:
            {
                ResponseExpectationValue = PLCCommandResponseExpectationEnum.MINOR_RESPONSE;
                break;
            }

            case PLCCommandAndQueryTypeEnum.SET_CONFIGURATION:
            {
                ResponseExpectationValue = PLCCommandResponseExpectationEnum.MINOR_RESPONSE;

                int StartSpeedAzimuth    = (int)MessageParameters[0];
                int StartSpeedElevation  = (int)MessageParameters[1];
                int HomeTimeoutAzimuth   = (int)MessageParameters[2];
                int HomeTimeoutElevation = (int)MessageParameters[3];

                NetOutgoingMessage[3] = 0x84;
                NetOutgoingMessage[4] = 0x00;
                NetOutgoingMessage[5] = 0x00;
                NetOutgoingMessage[6] = 0x00;

                NetOutgoingMessage[7]  = 0x0;
                NetOutgoingMessage[8]  = (byte)(StartSpeedAzimuth / 0xFFFF);
                NetOutgoingMessage[9]  = (byte)((StartSpeedAzimuth >> 8) & 0xFF);
                NetOutgoingMessage[10] = (byte)(StartSpeedAzimuth & 0xFF);

                NetOutgoingMessage[11] = 0x0;
                NetOutgoingMessage[12] = (byte)(StartSpeedElevation / 0xFFFF);
                NetOutgoingMessage[13] = (byte)((StartSpeedElevation >> 8) & 0xFF);
                NetOutgoingMessage[14] = (byte)(StartSpeedElevation & 0xFF);

                NetOutgoingMessage[15] = (byte)(HomeTimeoutAzimuth >> 8);
                NetOutgoingMessage[16] = (byte)(HomeTimeoutAzimuth & 0xFF);

                NetOutgoingMessage[17] = (byte)(HomeTimeoutElevation >> 8);
                NetOutgoingMessage[18] = (byte)(HomeTimeoutElevation & 0xFF);

                break;
            }

            case PLCCommandAndQueryTypeEnum.SET_OBJECTIVE_AZEL_POSITION:
            {
                ResponseExpectationValue = PLCCommandResponseExpectationEnum.MINOR_RESPONSE;

                Orientation ObjectiveOrientation = (Orientation)MessageParameters[0];
                Array.Copy(BitConverter.GetBytes(ObjectiveOrientation.Azimuth), 0, NetOutgoingMessage, 3, 8);
                Array.Copy(BitConverter.GetBytes(ObjectiveOrientation.Elevation), 0, NetOutgoingMessage, 11, 8);

                break;
            }

            case PLCCommandAndQueryTypeEnum.START_JOG_MOVEMENT:
            {
                ResponseExpectationValue = PLCCommandResponseExpectationEnum.MINOR_RESPONSE;

                RadioTelescopeAxisEnum AxisEnum = (RadioTelescopeAxisEnum)MessageParameters[0];
                int  AxisJogSpeed = (int)MessageParameters[1];
                bool JogClockwise = (bool)MessageParameters[2];

                switch (AxisEnum)
                {
                case RadioTelescopeAxisEnum.AZIMUTH:
                {
                    NetOutgoingMessage[3] = 0x1;
                    break;
                }

                case RadioTelescopeAxisEnum.ELEVATION:
                {
                    NetOutgoingMessage[3] = 0x2;
                    break;
                }

                default:
                {
                    throw new ArgumentException("Invalid RadioTelescopeAxisEnum value seen while preparing jog movement bytes: " + AxisEnum.ToString());
                }
                }

                NetOutgoingMessage[4] = 0x0;
                NetOutgoingMessage[5] = (byte)(AxisJogSpeed / 0xFFFF);
                NetOutgoingMessage[6] = (byte)((AxisJogSpeed >> 8) & 0xFF);
                NetOutgoingMessage[7] = (byte)(AxisJogSpeed & 0xFF);

                NetOutgoingMessage[8] = (byte)(JogClockwise ? 0x1 : 0x2);

                break;
            }

            case PLCCommandAndQueryTypeEnum.TRANSLATE_AZEL_POSITION:
            {
                ResponseExpectationValue = PLCCommandResponseExpectationEnum.MINOR_RESPONSE;

                RadioTelescopeAxisEnum AxisEnum = (RadioTelescopeAxisEnum)MessageParameters[0];
                int AxisJogSpeed = (int)MessageParameters[1];
                int position     = (int)MessageParameters[2];

                switch (AxisEnum)
                {
                case RadioTelescopeAxisEnum.AZIMUTH:
                {
                    NetOutgoingMessage[3] = 0x1;
                    break;
                }

                case RadioTelescopeAxisEnum.ELEVATION:
                {
                    NetOutgoingMessage[3] = 0x2;
                    break;
                }

                default:
                {
                    throw new ArgumentException("Invalid RadioTelescopeAxisEnum value seen while preparing relative movement bytes: " + AxisEnum.ToString());
                }
                }

                NetOutgoingMessage[4] = 0x0;
                NetOutgoingMessage[5] = (byte)(AxisJogSpeed / 0xFFFF);
                NetOutgoingMessage[6] = (byte)((AxisJogSpeed >> 8) & 0xFF);
                NetOutgoingMessage[7] = (byte)(AxisJogSpeed & 0xFF);

                if (position > 0)
                {
                    NetOutgoingMessage[8]  = 0x0;
                    NetOutgoingMessage[9]  = (byte)(position / 0xFFFF);
                    NetOutgoingMessage[10] = (byte)((position >> 8) & 0xFF);
                    NetOutgoingMessage[11] = (byte)(position & 0xFF);
                }
                else
                {
                    NetOutgoingMessage[8]  = 0xFF;
                    NetOutgoingMessage[9]  = (byte)((position / 0xFFFF) - 1);
                    NetOutgoingMessage[10] = (byte)((position >> 8) & 0xFF);
                    NetOutgoingMessage[11] = (byte)(position & 0xFF);
                }

                break;
            }

            default:
            {
                throw new ArgumentException("Illegal PLCCommandAndQueryTypeEnum value: " + MessageType.ToString());
            }
            }

            NetOutgoingMessage[2] += (byte)(PLCCommandResponseExpectationConversionHelper.ConvertToByte(ResponseExpectationValue) * 0x40);

            // This is the expected response size of anything from the PLC (simulated or real), minor or full response.
            // See the TCP/IP packet contents google sheets file describing this under Wiki Documentation -> Control Room in the shared GDrive
            byte ExpectedResponseSize = (ResponseExpectationValue == PLCCommandResponseExpectationEnum.FULL_RESPONSE) ? (byte)0x13 : (byte)0x3;

            return(SendMessageWithResponse(NetOutgoingMessage, ExpectedResponseSize));
        }
 public override bool MotorsCurrentlyMoving(RadioTelescopeAxisEnum axis = RadioTelescopeAxisEnum.BOTH)
 {
     throw new NotImplementedException();
 }
 public override RadioTelescopeDirectionEnum GetRadioTelescopeDirectionEnum(RadioTelescopeAxisEnum axis)
 {
     throw new NotImplementedException();
 }
 /// <summary>
 /// Gets the direction that the specfied axis is moving.
 /// </summary>
 /// <param name="axis">Azimuth or elevation.</param>
 /// <returns>The direction that the specfied axis is spinning.</returns>
 public abstract RadioTelescopeDirectionEnum GetRadioTelescopeDirectionEnum(RadioTelescopeAxisEnum axis);
示例#21
0
 public override bool[] GET_MCU_Status(RadioTelescopeAxisEnum axis)
 {
     return(driver.GET_MCU_Status(axis));
 }
示例#22
0
 public abstract bool Controled_stop(RadioTelescopeAxisEnum axis, bool both);
示例#23
0
 public override bool MotorsCurrentlyMoving(RadioTelescopeAxisEnum axis = RadioTelescopeAxisEnum.BOTH)
 {
     return(driver.MotorsCurrentlyMoving(axis));
 }
示例#24
0
        /// <summary>
        /// Method used to request to start jogging the Radio Telescope's elevation
        /// at a speed (in RPM), in either the clockwise or counter-clockwise direction.
        /// </summary>
        public MovementResult StartRadioTelescopeJog(double speed, RadioTelescopeDirectionEnum direction, RadioTelescopeAxisEnum axis)
        {
            MovementResult result = MovementResult.None;

            // Return if incoming priority is equal to or less than current movement
            if ((MovementPriority.Jog - 1) <= RadioTelescope.PLCDriver.CurrentMovementPriority)
            {
                return(MovementResult.AlreadyMoving);
            }

            // We only want to do this if it is safe to do so. Return false if not
            if (!AllSensorsSafe)
            {
                return(MovementResult.SensorsNotSafe);
            }

            // If a lower-priority movement was running, safely interrupt it.
            if (RadioTelescope.PLCDriver.InterruptMovementAndWaitUntilStopped())
            {
                return(MovementResult.StoppingCurrentMove);
            }

            // If the thread is locked (two moves coming in at the same time), return
            if (Monitor.TryEnter(MovementLock))
            {
                RadioTelescope.PLCDriver.CurrentMovementPriority = MovementPriority.Jog;

                double azSpeed = 0;
                double elSpeed = 0;

                if (axis == RadioTelescopeAxisEnum.AZIMUTH)
                {
                    azSpeed = speed;
                }
                else
                {
                    elSpeed = speed;
                }

                result = RadioTelescope.PLCDriver.StartBothAxesJog(azSpeed, direction, elSpeed, direction);

                Monitor.Exit(MovementLock);
            }
            else
            {
                result = MovementResult.AlreadyMoving;
            }

            return(result);
        }