예제 #1
0
        public void updateBlocks()
        {
            List <IMyAssembler>      tempAssemblers = new List <IMyAssembler>();
            List <IMyRefinery>       tempRefineries = new List <IMyRefinery>();
            List <IMyCargoContainer> tempContainers = new List <IMyCargoContainer>();
            List <IMyShipConnector>  tempEjector    = new List <IMyShipConnector>();
            List <IMyTimerBlock>     tempTimers     = new List <IMyTimerBlock>();
            List <IMyTextPanel>      tempPanels     = new List <IMyTextPanel>();

            group.GetBlocksOfType <IMyAssembler>(tempAssemblers);
            group.GetBlocksOfType <IMyRefinery>(tempRefineries);
            group.GetBlocksOfType <IMyCargoContainer>(tempContainers);
            group.GetBlocksOfType <IMyShipConnector>(tempEjector);
            group.GetBlocksOfType <IMyTimerBlock>(tempTimers);
            group.GetBlocksOfType <IMyTextPanel>(tempPanels);
            if (tempTimers.Count > 0)
            {
                if (timer != tempTimers[0])
                {
                    timer = tempTimers[0];
                    Echo("Timer block detected, program is set to run of the timer instead of automatic update");
                }
                timer.StartCountdown();
            }
            setupAssemblers(tempAssemblers);
            setupRefineries(tempRefineries);
            setupContainers(tempContainers);
            setupPanels(tempPanels);
            setupEjectors(tempEjector);
        }
예제 #2
0
        void doSubModuleTimerTriggers(string sKeyword = "[WCCS]")
        {
            List <IMyTerminalBlock> blocks = new List <IMyTerminalBlock>();

            IMyTimerBlock theTriggerTimer = null;

            if (dTimers.ContainsKey(sKeyword))
            {
                blocks = dTimers[sKeyword];
            }
            else
            {
                blocks = GetBlocksContains <IMyTerminalBlock>(sKeyword);
                dTimers.Add(sKeyword, blocks);
            }

            for (int i = 0; i < blocks.Count; i++)
            {
                theTriggerTimer = blocks[i] as IMyTimerBlock;
                if (theTriggerTimer != null)
                {
//            Echo("dSMT:" + blocks[i].CustomName);
                    theTriggerTimer.ApplyAction("TriggerNow");
                }
            }
        }
예제 #3
0
            StateMaschinePage[] CreateStateMaschine()
            {
                timeoutTimer = parent.GridTerminalSystem.GetBlockWithName("Timeout Trigger") as IMyTimerBlock;

                int lengthStateTable = Enum.GetNames(typeof(State)).Length - 2;

                StateMaschinePage[] stateMaschine = new StateMaschinePage[lengthStateTable];
                for (int i = 0; i < lengthStateTable; i++)
                {
                    stateMaschine[i] = new StateMaschinePage();
                }
                FillStateTable(stateMaschine);

                //Check if logic part is missing------------------------------------------
                if (timeoutTimer == null)
                {
                    lcdHandler.logMessage("Timer not found, should be named 'Timeout Trigger'", Tags.STM, Labels.cERR);
                    currentState = State.Error;
                    return(null);
                }
                else
                {
                    lcdHandler.logMessage("State Maschine operational", Tags.STM, Labels.BOOT);
                    currentState = State.Idle;
                    return(stateMaschine);
                }
                //---------------------------------------------------------------------------
            }
예제 #4
0
        public Program()
        {
            #region Constructor Help

            /* The constructor, called only once every session and
             * // always before any other method is called. Use it to
             * // initialize your script.
             * //
             * // The constructor is optional and can be removed if not
             * // needed.
             * //
             * // It's recommended to set RuntimeInfo.UpdateFrequency
             * // here, which will allow your script to run itself without a
             * timer block.*/
            #endregion

            _timer      = GridTerminalSystem.GetBlockWithName("MRF_Timer") as IMyTimerBlock;
            _lOn        = GridTerminalSystem.GetBlockWithName("MRF_lOn") as IMyInteriorLight;
            _lOff       = GridTerminalSystem.GetBlockWithName("MRF_lOff") as IMyInteriorLight;
            _rotor      = GridTerminalSystem.GetBlockWithName("MRF_Rotor") as IMyMotorStator;
            _debugPanel = GridTerminalSystem.GetBlockWithName("MRF_Debug") as IMyTextPanel;

            SetDrills();
            _debugPanel.WriteText(string.Join(",", _drills.Select(d => d.Name)));
        }
예제 #5
0
 public Program()
 {
     extPanel                = GridTerminalSystem.GetBlockWithName("lcdinfo") as IMyTextPanel;
     extPanel2               = GridTerminalSystem.GetBlockWithName("lcdinfo2") as IMyTextPanel;
     Timer                   = GridTerminalSystem.GetBlockWithName("Timer") as IMyTimerBlock;
     Timer.TriggerDelay      = 1;
     Runtime.UpdateFrequency = UpdateFrequency.Update1;
 }
예제 #6
0
 public Program()
 {
     //group names
     rotors_1        = "rotors x-1";
     rotors_2        = "rotors x-2";
     solar_direction = "solar direction";
     timer           = GridTerminalSystem.GetBlockWithName("Timer Solar") as IMyTimerBlock;
 }
예제 #7
0
        public IEnumerator <bool> Init()
        {
            cannonSettings = new INISerializer("CannonSettings");
            cannonSettings.AddValue("referenceName", x => x, "RCReference");
            cannonSettings.AddValue("speedCap", x => double.Parse(x), 104.38);
            cannonSettings.AddValue("launchVelocity", x => double.Parse(x), 100.0);
            cannonSettings.AddValue("sourceRotorTName", x => x, "[OrbitalCannonBase]_[Azimuth]");
            cannonSettings.AddValue("elevationTag", x => x, "[Elevation]");
            cannonSettings.AddValue("timerName", x => x, "CannonTimer");


            if (Me.CustomData == "")
            {
                string temp = Me.CustomData;
                cannonSettings.FirstSerialization(ref temp);
                Me.CustomData = temp;
            }
            else
            {
                cannonSettings.DeSerialize(Me.CustomData);
            }
            yield return(true);

            ingameTime = new IngameTime();
            GTSUtils   = new GridTerminalSystemUtils(Me, GridTerminalSystem);

            yield return(true);

            IMyShipController reference   = GridTerminalSystem.GetBlockWithName((string)cannonSettings.GetValue("referenceName")) as IMyShipController;
            IMyMotorStator    sourceRotor = GridTerminalSystem.GetBlockWithName((string)cannonSettings.GetValue("sourceRotorTName")) as IMyMotorStator;
            IMyTimerBlock     timer       = GridTerminalSystem.GetBlockWithName((string)cannonSettings.GetValue("timerName")) as IMyTimerBlock;

            Echo($"Getting blocks status:...\nreference: {reference != null}\nsourceRotor: {sourceRotor != null}");

            if (reference == null || sourceRotor == null)
            {
                throw new Exception("cant get blocks!");
            }

            yield return(true);

            targeter = new Targeter
                       (
                (double)cannonSettings.GetValue("speedCap"),
                (double)cannonSettings.GetValue("launchVelocity"),
                reference
                       );
            targeter.directionFoundCallback += TargetCalculatedCallback;

            yield return(true);

            cannon       = Cannon.CreateCannon(sourceRotor, GTSUtils, ingameTime, reference, (string)cannonSettings.GetValue("sourceRotorTName"), (string)cannonSettings.GetValue("elevationTag"));
            cannon.Timer = timer;
            yield return(true);

            Echo("Initialized!");
            initialized = true;
        }
예제 #8
0
 public Timer(BlockHelper blockHelper, string timerName)
 {
     this.blockHelper = blockHelper;
     this.timer       = this.blockHelper.GetBlockWithName(timerName) as IMyTimerBlock;
     if (this.timer == null)
     {
         throw new Exception("Unable to find a timer block called " + timerName);
     }
 }
예제 #9
0
 public Program()
 {
     m_LcdAccident   = GridTerminalSystem.GetBlockWithName(AccidentLCD) as IMyTextPanel;
     m_TimerAccident = GridTerminalSystem.GetBlockWithName(AccidentTimer) as IMyTimerBlock;
     if (Storage.Length > 0)
     {
         m_LastAccident = DateTime.Parse(Storage);
     }
 }
        private void Exec_Setup()
        {
            _projector = GetBlocksOfTypeWithName <IMyProjector>("_MTB").FirstOrDefault();
            _timer     = GetBlocksOfTypeWithName <IMyTimerBlock>("_MTB").FirstOrDefault();
            _welders   = GetBlocksOfTypeWithName <IMyShipWelder>("_MTB");
            _cutters   = GetBlocksOfTypeWithName <IMyThrust>("_MTB");
            _torpDock  = GetBlocksOfTypeWithName <IMyShipConnector>("_MTB").FirstOrDefault();
            _piston    = GetBlocksOfTypeWithName <IMyPistonBase>("_MTB").FirstOrDefault();

            EchoText(
                "==SETUP== \n" +
                "\n" +
                "Projector: " + ((_projector != null) ? "Ok ✅" : "Not found") + "\n" +
                "Timer: " + ((_timer != null) ? "Ok ✅" : "Not found") + "\n" +
                "Welders: " + ((_welders != null) ? (_welders.Count > 0) ? "Ok ✅" : "Not found" : "Not found") + " (" + _cutters.Count + ")" + "\n" +
                "Torpedo Dock: " + ((_torpDock != null) ? "Ok ✅" : "Not found") + "\n" +
                "Piston: " + ((_piston != null) ? "Ok ✅" : "Not found") + "\n" +
                "Cutters: " + ((_cutters != null) ? (_cutters.Count > 0) ? "Ok ✅" : "Not found" : "Not found") + " (" + _cutters.Count + ")"
                );

            if (_projector == null || _timer == null || _welders == null || _cutters == null || _torpDock == null)
            {
                return;
            }

            if (_cutters.Count == 0)
            {
                return;
            }

            _shipTag = ParseTag(_torpDock.CubeGrid.CustomName);

            _projector.CustomName = _shipTag + "_MTB_" + "Projector";
            _timer.CustomName     = _shipTag + "_MTB_" + "Timer"; //..setup timer actions automatically?
            _torpDock.CustomName  = _shipTag + "_MTB_" + "TorpedoDock";
            _piston.CustomName    = _shipTag + "_MTB_" + "Piston";

            //..name the welders
            for (int i = 0; i < _welders.Count; ++i)
            {
                IMyShipWelder w = _welders[i];
                w.Enabled    = false;
                w.CustomName = _shipTag + "_MTB_" + "Welder_" + (i + 1);
            }

            //..make sure all the cutters are off to begin with
            for (int i = 0; i < _cutters.Count; ++i)
            {
                IMyThrust t = _cutters[i];

                t.ThrustOverridePercentage = 1;
                t.Enabled    = false;
                t.CustomName = _shipTag + "_MTB_" + "Cutter_" + (i + 1);
            }
        }
예제 #11
0
        void Main(string argument)
        {
            Echo("Global Count: " + _globalCount);
            _globalCount++;
            if (argument != null)
            {
                Echo("Argument: " + argument);
                if (!argument.Equals(""))
                {
                    try
                    {
                        _count = int.Parse(argument);
                        Echo("Argument parsed as " + _count);
                    }
                    catch (Exception)
                    {
                        Echo("Argument not parsable");
                        _count = 0;
                    }
                }
            }
            else
            {
                Echo("Argument null");
                return;
            }
            if (_globalCount < 10)
            {
                string newArg = (_count + 1).ToString();
                Echo("Try: " + newArg);
                //Me.ApplyAction("Run");
                IMyProgrammableBlock prog = GridTerminalSystem.GetBlockWithName("Prog Loop 2") as IMyProgrammableBlock;
                if (prog != null)
                {
                    prog.ApplyAction("Run",
                                     new List <TerminalActionParameter>()
                    {
                        TerminalActionParameter.Get(newArg)
                    });
                }

                List <IMyTerminalBlock> blocks = new List <IMyTerminalBlock>();
                GridTerminalSystem.GetBlocksOfType <IMyTimerBlock>(blocks);
                if (blocks.Count > 0)
                {
                    IMyTimerBlock timer = blocks[0] as IMyTimerBlock;
                    if (timer != null)
                    {
                        timer.ApplyAction("TriggerNow");
                    }
                }
            }
        }
예제 #12
0
        bool FuncTest(IMyTimerBlock block)
        {
            //Timer Block
            //Interface name: IMyTimerBlock
            //Parent: IMyFunctionalBlock
            //Fields:
            bool IsCountingDown = block
                                  .IsCountingDown;
            float TriggerDelay = block.TriggerDelay;

            return(true);
        }
public Program()
{
    Echo("initializing...");
    for (int i = 1; i <= 7; i++)
    {
        lightsLeft.Add(GridTerminalSystem.GetBlockWithName("Hanger Door - A" + i) as IMyLightingBlock);
        lightsRight.Add(GridTerminalSystem.GetBlockWithName("Hanger Door - B" + i) as IMyLightingBlock);
    }
    piston1 = GridTerminalSystem.GetBlockWithName("Hanger Door Piston 1") as IMyPistonBase;
    piston2 = GridTerminalSystem.GetBlockWithName("Hanger Door Piston 2") as IMyPistonBase;
    timer   = GridTerminalSystem.GetBlockWithName("Timer Hanger Door Lights Off") as IMyTimerBlock;
    Echo("Init complete");
}
예제 #14
0
    private void KickTimer(ZACommons commons)
    {
        IMyTimerBlock timer = null;

        // Name takes priority over group
        if (TimerName != null)
        {
            var blocks = ZACommons.SearchBlocksOfName(commons.Blocks, TimerName,
                                                      block => block is IMyTimerBlock &&
                                                      ((IMyTimerBlock)block).Enabled);
            if (blocks.Count > 0)
            {
                timer = blocks[0] as IMyTimerBlock;
            }
        }
        if (timer == null && TimerGroup != null)
        {
            var group = commons.GetBlockGroupWithName(TimerGroup);
            if (group != null)
            {
                var blocks = ZACommons.GetBlocksOfType <IMyTimerBlock>(group.Blocks,
                                                                       block => block.CubeGrid == commons.Me.CubeGrid &&
                                                                       ((IMyTimerBlock)block).Enabled);
                timer = blocks.Count > 0 ? (IMyTimerBlock)blocks[0] : null;
            }
        }

        if (timer != null)
        {
            // Rules are simple. If we have something in the tick queue, trigger now.
            // Otherwise, set timer delay appropriately (minimum 1 second) and kick.
            // If you want sub-second accuracy, always use ticks.
            if (TickQueue.First != null)
            {
                timer.ApplyAction("TriggerNow");
            }
            else if (TimeQueue.First != null)
            {
                var next = (float)(TimeQueue.First.Value.When.TotalSeconds - TimeSinceStart.TotalSeconds);
                // Constrain appropriately (not sure if this will be done for us or if it
                // will just throw). Just do it to be safe.
                next = Math.Max(next, timer.GetMinimum <float>("TriggerDelay"));
                next = Math.Min(next, timer.GetMaximum <float>("TriggerDelay"));

                timer.SetValue <float>("TriggerDelay", next);
                timer.ApplyAction("Start");
            }
            // NB If both queues are empty, we stop running
        }
    }
예제 #15
0
 public override void Init(MyObjectBuilder_EntityBase objectBuilder)
 {
     try
     {
         npcCrewBlock = Entity as IMyTimerBlock;
         NeedsUpdate  = MyEntityUpdateEnum.EACH_FRAME;
         npcCrewBlock.CubeGrid.ColorBlocks(npcCrewBlock.SlimBlock.Position, npcCrewBlock.SlimBlock.Position, Color.Red.ColorToHSV());
         //MyAPIGateway.Utilities.ShowMessage("DEBUG", "Init Ran");
     }
     catch (Exception e)
     {
         MyVisualScriptLogicProvider.ShowNotificationToAll("Init Error" + e, 10000, "Red");
     }
 }
예제 #16
0
        // public Quaternion GetGridRotationFromWorldGrid()
        // {

        // }



        // Attempts to measure gyro torque
        public void gyroForce()
        {
            string state = getLcd("DebugState").GetPublicText();

            LcdClear("DebugState");
            //TODO: Determine parametres of gyro acceleration and top speed
            IMyGyro    gyro = GetBlock <IMyGyro>("DefaultGyro", true);
            int        t;
            Quaternion worldOrientation;

            if (state.Equals("") || state.Equals("reset"))
            {
                LcdClear();
                // Must activate override before assigning values!!!
                gyro.GyroOverride = true;
                gyro.Yaw          = 1;
                //GyroSetOverrideToRollPitchYaw(gyro, 0, 0, 1, true, AngleUnit.FREQUENCY);
                t = 0;
                worldOrientation = GetGridRotation();
            }
            else if (state.Equals("stop"))
            {
                gyro.Yaw          = 0;
                gyro.GyroOverride = false;
                LcdPrint("reset", "DebugState");

                IMyTimerBlock timer = GetBlock <IMyTimerBlock>("DebugTimer");
                timer.StopCountdown();

                int shipMass = getRemoteControl("", true).CalculateShipMass().PhysicalMass;
                LcdPrintln("Mass:" + shipMass);
                return;
            }
            else
            {
                string[] data = state.Split('\n');
                worldOrientation = QuaternionFromRawString(data[1]);
                t = Convert.ToInt32(data[0]);
            }
            MyBlockOrientation orientation = gyro.Orientation;
            Quaternion         quat        = GetGridRotation();

            quat = Quaternion.Multiply(worldOrientation, quat);
            //orientation.GetQuaternion(out quat);
            QuaternionToRollPitchYawDebugPrint(quat, "t:" + t); // Already prefixes "RPY" to front
            t++;
            LcdPrintln(t.ToString(), "DebugState");
            LcdPrint(QuaternionToRawString(worldOrientation), "DebugState");
        }
예제 #17
0
        public Program()
        {
            //GETS BLOCKS VIA THEIR NAMES
            piston1 = GridTerminalSystem.GetBlockWithName("piston 1 (main dock)") as IMyPistonBase;
            piston2 = GridTerminalSystem.GetBlockWithName("piston 2 (main dock)") as IMyPistonBase;
            piston3 = GridTerminalSystem.GetBlockWithName("piston 3 (main dock)") as IMyPistonBase;
            piston4 = GridTerminalSystem.GetBlockWithName("piston 4 (main dock)") as IMyPistonBase;

            rotor1 = GridTerminalSystem.GetBlockWithName("advanced rotor 1 (main dock)") as IMyMotorStator;
            rotor2 = GridTerminalSystem.GetBlockWithName("advanced rotor 2 (main dock)") as IMyMotorStator;

            connector = GridTerminalSystem.GetBlockWithName("connector (main dock)") as IMyShipConnector;

            timer = GridTerminalSystem.GetBlockWithName("timer (main dock)") as IMyTimerBlock;
        }
예제 #18
0
        public void Panic()
        {
            IMyTimerBlock timer = ( IMyTimerBlock )GridTerminalSystem.GetBlockWithName("TimerT");

            if (timer != null)
            {
                if (timer.IsCountingDown)
                {
                    Engage();
                }
                else
                {
                    Idle();
                }
            }
        }
예제 #19
0
    public Program()
    {
        Runtime.UpdateFrequency = UpdateFrequency.Update10;
        // Retrieve the blocks we're going to use.
        _timer      = GridTerminalSystem.GetBlockWithName("Timer Block") as IMyTimerBlock;
        _panelLight = GridTerminalSystem.GetBlockWithName("Interior Light") as IMyInteriorLight;
        _textPanel  = GridTerminalSystem.GetBlockWithName("LCD Panel") as IMyTextPanel;

        // Initialize our state machine
        _stateMachine = RunStuffOverTime().GetEnumerator();

        // Start the timer to run the first instruction set. Depending on your script, you may want to use
        // TriggerNow rather than Start. Just be very careful with that, you can easily bog down your
        // game that way.
        _timer.ApplyAction("Start");
    }
예제 #20
0
    public void Main(string args)
    {
        CurrentTick++;

        float capacity = 0f;
        float volume   = 0f;
        float weight   = 0f;

        IMyTimerBlock           timer           = GridTerminalSystem.GetBlockWithName("Timer") as IMyTimerBlock;
        IMyTextPanel            LCDLeft         = GridTerminalSystem.GetBlockWithName("LCD Left") as IMyTextPanel;
        IMyTextPanel            LCDRight        = GridTerminalSystem.GetBlockWithName("LCD Right") as IMyTextPanel;
        List <IMyTerminalBlock> cargoContainers = new List <IMyTerminalBlock>();
        List <IMyTerminalBlock> shipDrills      = new List <IMyTerminalBlock>();

        GridTerminalSystem.SearchBlocksOfName("Cargo", cargoContainers);
        GridTerminalSystem.SearchBlocksOfName("Drill", shipDrills);
        timer.ApplyAction("TriggerNow");

        if (CurrentTick % Clock != 0)
        {
            return;
        }

        if (LCDLeft != null & LCDRight != null)
        {
            foreach (IMyShipDrill cont in shipDrills)
            {
                capacity += (float)cont.GetInventory(0).MaxVolume;
                volume   += (float)cont.GetInventory(0).CurrentVolume;
                weight   += (float)cont.GetInventory(0).CurrentMass;
            }

            foreach (IMyCargoContainer cont in cargoContainers)
            {
                capacity += (float)cont.GetInventory(0).MaxVolume;
                volume   += (float)cont.GetInventory(0).CurrentVolume;
                weight   += (float)cont.GetInventory(0).CurrentMass;
            }

            Echo($"Capacity: {capacity}");
            Echo($"Used:     {volume}");
            Echo($"Percentage: {volume / capacity}");

            LCDLeft.WriteText("Емкость: " + capacity + "\nЗанято: " + volume + "\n");
            LCDRight.WriteText(cargoContainers.Count.ToString());
        }
    }
예제 #21
0
            public PinpointScanSystem(Program program)
            {
                _program = program;

                detectedList = new List <MyDetectedEntityInfo>();

                IMyBlockGroup scanSystemGroup = _program.GridTerminalSystem.GetBlockGroupWithName(SCAN_SYSTEM_GROUP);

                if (scanSystemGroup == null)
                {
                    throw new Exception($"No {SCAN_SYSTEM_GROUP} group defined.");
                }
                cameras = new List <IMyCameraBlock>();
                scanSystemGroup.GetBlocksOfType <IMyCameraBlock>(cameras);
                if (cameras.Count == 0)
                {
                    throw new Exception("No camera found in group.");
                }
                displays = new List <IMyTextPanel>();
                scanSystemGroup.GetBlocksOfType <IMyTextPanel>(displays);
                if (cameras.Count == 0)
                {
                    throw new Exception("No text pannel found in group.");
                }

                if (TIMERBLOCKTRIGGER != string.Empty)
                {
                    //we are to trigger a block on contact
                    _program.Echo("Searching timmer block...");
                    trigger = _program.GridTerminalSystem.GetBlockWithName(TIMERBLOCKTRIGGER) as IMyTimerBlock;
                    if (trigger != null)
                    {
                        _program.Echo($"Timer {trigger.CustomName} found.");
                        triggerBlockOnContact = true;
                    }
                    else
                    {
                        _program.Echo($"Timer {TIMERBLOCKTRIGGER} not found.");
                    }
                }

                //Enable raycast for cameras
                foreach (var camera in cameras)
                {
                    camera.EnableRaycast = true;
                }
            }
예제 #22
0
        public Program()
        {
            // The constructor, called only once every session and
            // always before any other method is called. Use it to
            // initialize your script.
            //
            // The constructor is optional and can be removed if not
            // needed.
            //
            // It's recommended to set RuntimeInfo.UpdateFrequency
            // here, which will allow your script to run itself without a
            // timer block.

            _timer       = GridTerminalSystem.GetBlockWithName("MSD_Timer") as IMyTimerBlock;
            _pistonInOut = GridTerminalSystem.GetBlockWithName("MSD_pInOut") as IMyPistonBase;
            _pistonSlide = GridTerminalSystem.GetBlockWithName("MSD_pSlide") as IMyPistonBase;
            _gear        = GridTerminalSystem.GetBlockWithName("MSD_Gear") as IMyLandingGear;
        }
예제 #23
0
        void TriggerTimer(string Argument)
        {
            string targetTag = strTriggerTimerTag;

            string[] argSplit = Argument.Split(' ');
            if (argSplit.Length > 1)
            {
                targetTag = argSplit[1];
            }

            List <IMyTerminalBlock> blocks       = GetBlocksWithName <IMyTimerBlock>(targetTag);
            IMyTimerBlock           commandTimer = null;

            commandTimer = ReturnClosest(blocks) as IMyTimerBlock;

            if (commandTimer != null)
            {
                commandTimer.ApplyAction("TriggerNow");
            }
        }
예제 #24
0
    public void Main(string arg)
    {
        //tickCount++;
        if (timer == null)
        {
            timer = GridTerminalSystem.GetBlockWithName("Timer") as IMyTimerBlock;
        }
        if (textPanel == null)
        {
            textPanel = GridTerminalSystem.GetBlockWithName("LCD") as IMyTextPanel;
        }
        if (remCon == null)
        {
            remCon = GridTerminalSystem.GetBlockWithName("RemCon") as IMyRemoteControl;
        }

        switch (arg)
        {
        case "start":
        {
            stop = false; break;
        }

        case "stop":
        {
            stop = true; break;
        }

        default: break;
        }

        GyroOverride(true, GetNavAngles(testVector1) * gyroMult, 1);
        if (!stop)
        {
            timer.ApplyAction("TriggerNow");
        }
        else
        {
            GyroOverride(false, new Vector3(0, 0, 0));
        }
    }
예제 #25
0
        bool CollectBlocks(IMyTerminalBlock block)
        {
            if (!block.IsSameConstructAs(Context.Reference))
            {
                return(false);
            }
            if (block.CustomName.Contains("[X]"))
            {
                return(false);
            }
            if (block is IMyMotorSuspension)
            {
                Suspensions.Add(block as IMyMotorSuspension);
            }
            if (block is IMyShipController)
            {
                Controllers.Add(block as IMyShipController);
            }
            if (block is IMyGasGenerator)
            {
                O2Generators.Add(block as IMyGasGenerator);
            }
            if (block is IMyGasTank)
            {
                GasTanks.Add(block as IMyGasTank);
            }
            if (block is IMyCockpit)
            {
                Cockpits.Add(block as IMyCockpit);
            }
            if (block is IMyGyro)
            {
                Gyros.Add(block as IMyGyro);
            }
            if (block is IMyTimerBlock && block.CustomName.Contains("[W]"))
            {
                AddWheelTimer = block as IMyTimerBlock;
            }

            return(false);
        }
예제 #26
0
파일: Program.cs 프로젝트: fishykins/CAM
        /// <summary>
        /// Initialize script here. This is essentially "free" computing, and wont affect the program average runtime...
        /// </summary>
        public Program()
        {
            //Compile core variables
            manualProgram = new ManualProgram(this);
            gridAnalyser  = new GridAnalyser(this);
            output        = new Output(this, programTag);
            timer         = gridAnalyser.GetTimer(programTag);
            diagnostics   = new Diagnostics(this, diagnosticTag);
            diagnostics.Start();

            //Add routines here
            routines.Add(new Logistics(this, logisticsTag));
            routines.Add(new Hangar(this, hangarTag));
            routines.Add(new Factory(this, factoryTag));
            //routines.Add(new AirlockManager(this, airlockTag));

            InitRoutines();

            //Set how often this runs
            Runtime.UpdateFrequency = UpdateFrequency.Update1;
        }
예제 #27
0
        public Program()

        {
            // The constructor, called only once every session and
            // always before any other method is called. Use it to
            // initialize your script.
            //
            // The constructor is optional and can be removed if not
            // needed.
            //
            // It's recommended to set RuntimeInfo.UpdateFrequency
            // here, which will allow your script to run itself without a
            // timer block.

            rotor = GridTerminalSystem.GetBlockWithName("Rotor spotligt") as IMyMotorStator;
            me    = GridTerminalSystem.GetBlockWithName("Programmable block Spotlight") as IMyProgrammableBlock;
            timer = GridTerminalSystem.GetBlockWithName("Timer Block spotlight") as IMyTimerBlock;
            //timer.ApplyAction("Start");

            rotorsControl = new List <RotorControlData>();
            statusPos     = 0;
        }
예제 #28
0
 public void Main(string argument, UpdateType updateSource)
 {
     // The main entry point of the script, invoked every time
     // one of the programmable block's Run actions are invoked,
     // or the script updates itself. The updateSource argument
     // describes where the update came from. Be aware that the
     // updateSource is a  bitfield  and might contain more than 
     // one update type.
     // 
     // The method itself is required, but the arguments above
     // can be removed if not needed.
     IMyTimerBlock DoorOpenBlock = GridTerminalSystem.GetBlockWithName("DoorOpenTimer") as IMyTimerBlock;
     IMyTimerBlock DoorCloseBlock = GridTerminalSystem.GetBlockWithName("DoorCloseTimer") as IMyTimerBlock;
     IMyMotorStator DoorRotor = GridTerminalSystem.GetBlockWithName("DoorRotor") as IMyMotorStator;
     double angle = (Math.Round(DoorRotor.Angle * (180 / Math.PI)));
     Echo(angle.ToString());
     if(DoorRotor.TargetVelocityRPM == 0)
     {
         if (angle < 330 )
         {
             DoorCloseBlock.Trigger();
         }
         else
         {
             DoorOpenBlock.Trigger();
         }
     }
     else
     {
         if(DoorRotor.TargetVelocityRPM < 0)
         {
             DoorCloseBlock.Trigger();
         }
         else
         {
             DoorOpenBlock.Trigger();
         }
     }
 }
        public Program()
        {
            Runtime.UpdateFrequency = UpdateFrequency.Update1;

            IMyBlockGroup iceCargoGroup = GridTerminalSystem.GetBlockGroupWithName("Ice Cargo - Power");

            iceCargoGroup.GetBlocks(iceCargoTerminalBlocks);
            IMyBlockGroup hydroTankGroup = GridTerminalSystem.GetBlockGroupWithName("Hydro Tanks");

            hydroTankGroup.GetBlocks(hydroTankTerminalBlocks);

            IMyBlockGroup generatorGroup = GridTerminalSystem.GetBlockGroupWithName("Hydro Engines - Power");

            generatorGroup.GetBlocks(generatorTerminalBlocks);
            IMyBlockGroup batteryGroup = GridTerminalSystem.GetBlockGroupWithName("Base Batteries");

            batteryGroup.GetBlocks(batteryTerminalBlocks);

            startMining = GridTerminalSystem.GetBlockWithName("Start Mining") as IMyTimerBlock;
            stopMining  = GridTerminalSystem.GetBlockWithName("Stop Mining") as IMyTimerBlock;

            debug = GridTerminalSystem.GetBlockWithName("debug") as IMyTextPanel;
        }
            public Missile(
                List <IMyGyro> gyros,
                List <IMyThrust> thrusters,
                IMyShipMergeBlock mergeBlock = null,
                IMyUserControllableGun gun   = null,
                List <IMyWarhead> warheads   = null,
                IMyTimerBlock customP        = null,
                IMySensorBlock sensor        = null)
            {
                // Initialize
                _gyros      = gyros;
                _thrusters  = thrusters;
                _mergeBlock = mergeBlock;
                _gun        = gun;
                _warheads   = warheads;
                _customP    = customP;
                _sensor     = sensor;

                // Check if the missile is valid
                if (_gyros == null)
                {
                    Error |= MissileError.MissingGyros;
                }
                if (_thrusters == null)
                {
                    Error |= MissileError.MissingThrust;
                }
                if (_mergeBlock == null && gun == null && _warheads == null)
                {
                    Error |= MissileError.MissingDetach;
                }
                if (Error != MissileError.None)
                {
                    Error ^= MissileError.None;
                    return;
                }
            }
예제 #31
0
        void Init()
        {
            //Shift[0].x = 0; // Example for hard coded Datum Shift 
            //Shift[0].y = 0; 
            //Shift[0].z = 0; 

            i++;
            MainScreen("init", true);
            Debug("", false);

            // Rotors on arm 
            AR1BaseTop = (IMyTerminalBlock)GridTerminalSystem.GetBlockWithName(AR1BaseTopName); // BaseTop Rotor 
            AR2BasePole = (IMyTerminalBlock)GridTerminalSystem.GetBlockWithName(AR2BasePoleName); // BasePole Rotor 
            AR3Pole = (IMyTerminalBlock)GridTerminalSystem.GetBlockWithName(AR3PoleName); // Pole Rotor 
            AR4PoleWrist = (IMyTerminalBlock)GridTerminalSystem.GetBlockWithName(AR4PoleWristName); // PoleWrist Rotor 
            AR5WristTop = (IMyTerminalBlock)GridTerminalSystem.GetBlockWithName(AR5WristTopName); // WristTop Rotor 

            ARB = null;//(IMyTerminalBlock)GridTerminalSystem.GetBlockWithName(ARBAxisName); // WristTop Rotor 
            ARBTip = null;//(IMyTerminalBlock)GridTerminalSystem.GetBlockWithName(ARBTipName); // WristTop Rotor 
            ARC = null;//(IMyTerminalBlock)GridTerminalSystem.GetBlockWithName(ARCAxisName); // WristTop Rotor 

            // Timer Block for main control loop 
            TB = (IMyTimerBlock)GridTerminalSystem.GetBlockWithName(TBName);

            // ####### Optional Blocks ####### 

            //Lighting Block for moving indication (for easy Automation usage) 
            IL = (IMyLightingBlock)GridTerminalSystem.GetBlockWithName(ILName);

            // Main Screen LCD Display (for Coordinate Display) 
            Mscreen = (IMyTextPanel)GridTerminalSystem.GetBlockWithName(MscreenName);

            // Feed Screen LCD Display (for big display of Feed and Step Size) 
            Fscreen = (IMyTextPanel)GridTerminalSystem.GetBlockWithName(FscreenName);

            // easy Automation LCD Screen, Write Saved Positions to public screen (for SavePos command) 
            AutScreen = (IMyTextPanel)GridTerminalSystem.GetBlockWithName(AutScreenName);


            if (AR1BaseTop == null) { throw new Exception("Error: AR1 BaseTop Block not found"); }
            if (AR2BasePole == null) { throw new Exception("Error: AR2 BasePole Block not found"); }
            if (AR3Pole == null) { throw new Exception("Error: AR3 Pole Block not found"); }
            if (AR4PoleWrist == null) { throw new Exception("Error: AR4 PoleWrist Block not found"); }
            if (AR5WristTop == null) { throw new Exception("Error: AR5 WristTop Block not found"); }

            if (TB == null) { throw new Exception("Error: Timer Block not found"); }

            if (Mscreen == null) { Echo("Warning: MainScreen Block not found"); }
            if (Fscreen == null) { Echo("Warning: FeedScreen Block not found"); }

            if (IL == null) { Echo("Warning: IL Arm Block not found"); }

            if (AutScreen == null) { Echo("Warning: easy Automation Screen Block not found"); }

            TargetTime = DateTime.Now.AddTicks(Zykluszeit * TimeSpan.TicksPerMillisecond);

            EndPosReached = 1;
            IstToEndInterpolIter = 5 * (SpeedUpMult - 1); // Start value for Path Speed Up 

            ang1 = GetRotorAngle(AR2BasePole);
            ang2 = GetRotorAngle(AR3Pole);
            ang3 = GetRotorAngle(AR4PoleWrist);
            ang4 = GetRotorAngle(AR1BaseTop);
            ang5 = GetRotorAngle(AR5WristTop);

            MaStart = SmartAngle((ang5 - (ang4 * (-ToolDir))) * (-ToolDir));
            MaEnd = MaStart;


            if (ARB != null)
            {
                angB = GetRotorAngle(ARB);
                MbStart = SmartAngle(angB);
                MbEnd = MbStart;
            }
            if (ARC != null)
            {
                angC = GetRotorAngle(ARC);
                McStart = SmartAngle(angC);
                McEnd = McStart;
            }


            //~ MainScreen("Ist Angles\nBasePole   "+  Math.Round(ang1,3)+"\n"+ 
            //~ "Pole       "+ Math.Round(ang2,3)+"\n"+ 
            //~ "PoleWrist  "+ Math.Round(ang3,3)+"\n"+ 
            //~ "BaseTop    "+ Math.Round(ang4,3)+"\n"+ 
            //~ "WristTop   "+ Math.Round(ang5,3)+"\n", true); 

            CalculateIstPos(ang1, ang2, ang4, ang5);
            //~ MainScreen("Ist Pos   -> MxIst: "+r2s(MxIst)+" MyIst: "+r2s(MyIst)+" MzIst: "+r2s(MzIst), true) ; 
            MxStart = MxIst; MyStart = MyIst; MzStart = MzIst; // Start Pos of Iteration (Start position) 
            //~ MainScreen("iStart Pos -> MxStart: "+r2s(MxStart)+" MyStart: "+r2s(MyStart)+" MzStart: "+r2s(MzStart), true) ; 
            MxEnd = MxIst; MyEnd = MyIst; MzEnd = MzIst;      // Final Pos of Iteration 

            MxEndOrg = MxIst; MyEndOrg = MyIst; MzEndOrg = MzIst;

            CalculateAngles(MxStart, MyStart, MzStart);

            //~ MainScreen("Start Angles\nBasePole   "+ Math.Round(BasePoleAng,1) +"\n"+ 
            //~ "Pole       "+ Math.Round(PoleAng,1) +"\n"+ 
            //~ "PoleWrist  "+ Math.Round(PoleWristAng,1) +"\n"+ 
            //~ "BaseTop    "+ Math.Round(BaseTopAng,1) +"\n"+ 
            //~ "WristTop   "+ Math.Round(WristTopAng,1)+"\n",true); 

        } 
예제 #32
0
        private void init()
        {
            #region initialization

            oldPBName = Me.CustomName;

            unique_id = (new Random()).Next();

            all_blocks_found = true;

            autopilot_en = true;

            location_name = "UNKNOWN";

            // For spinner
            counter = 0;

            string parse = Me.CustomName.Replace(BLOCK_PREFIX, "");
            int id1 = Me.CustomName.IndexOf('[');
            int id2 = Me.CustomName.IndexOf(']');
            if (id1 >= 0 && id2 >= 0)
            {
                parse = parse.Substring(id1 + 1, id2 - id1 - 1);
            }
            else
            {
                parse = "";
            }

            BaconArgs Args = BaconArgs.parse(parse);

            IS_BASE = (Args.getFlag('b') > 0);

            DOCK_LEFT = (Args.getFlag('l') > 0);

            IS_PLANET = (Args.getFlag('p') > 0);

            if (IS_PLANET) IS_BASE = true;

            List<string> nameArg = Args.getOption("name");

            if (nameArg.Count > 0 && nameArg[0] != null)
            {
                location_name = nameArg[0];
            }

            // Set all known blocks to null or clear lists
            lcdPanel = null;
            messageReceiver = null;
            WANProgram = null;
            connector = null;
            remoteControl = null;
            door = null;
            timer = null;
            landLight = null;
            mainGear = 0;

            gyros.Clear();
            destinations.Clear();
            gears.Clear();

            // Get all blocks
            List<IMyTerminalBlock> blks = new List<IMyTerminalBlock>();
            GridTerminalSystem.SearchBlocksOfName(BLOCK_PREFIX, blks, hasPrefix);
            num_blocks_found = blks.Count;

            // Assign blocks to variables as appropriate
            foreach (var blk in blks)
            {
                // LCD panel for printing
                if (blk is IMyTextPanel)
                {
                    lcdPanel = blk as IMyTextPanel;
                    lcdPanel.ShowPublicTextOnScreen();
                    lcdPanel.SetValueFloat("FontSize", 1.2f);
                }
                // Wico Area Network programmable block
                else if (blk is IMyProgrammableBlock && !blk.Equals(Me))
                {
                    WANProgram = blk as IMyProgrammableBlock;
                }
                // Autopilot
                else if (!IS_BASE && blk is IMyRemoteControl)
                {
                    remoteControl = blk as IMyRemoteControl;
                }
                /* Ship or station connector for docking
                 * Used to connect to station and for orientation info
                 */
                else if (!IS_PLANET && blk is IMyShipConnector)
                {
                    connector = blk as IMyShipConnector;
                }
                /* Door used for docking; used for orientation information
                 * since it's more obvious which way a door faces than a connector
                 */
                else if (!IS_PLANET && blk is IMyDoor)
                {
                    door = blk as IMyDoor;
                }
                // Gyros for ship orientation
                else if (!IS_BASE && blk is IMyGyro)
                {
                    IMyGyro g = blk as IMyGyro;
                    gyros.Add(g);

                }
                // Timer block so that we can orient ship properly - requires multiple calls/sec
                else if (!IS_BASE && blk is IMyTimerBlock)
                {
                    timer = blk as IMyTimerBlock;
                    timer.SetValueFloat("TriggerDelay", 1.0f);
                }
                // Light (interior or spotlight) determines where we will land
                else if (IS_BASE && IS_PLANET && blk is IMyInteriorLight)
                {
                    landLight = blk as IMyInteriorLight;
                }
                // Landing gear....
                else if (!IS_BASE && blk is IMyLandingGear)
                {
                    IMyLandingGear gear = blk as IMyLandingGear;
                    gears.Add(gear);
                    if (gear.CustomName.ToLower().Contains("main"))
                    {
                        mainGear = gears.Count - 1;
                    }
                }
            }

            // Make sure all gyros reset
            resetGyros();

            // Clear block list
            blks.Clear();

            // Get text panel blocks used by Wico Area Network for communication
            GridTerminalSystem.GetBlocksOfType<IMyTextPanel>(blks, hasWANRPrefix);

            if (blks.Count == 0)
            {
                Echo("Error: Can't find message received text panel for Wico Area Network");
                all_blocks_found = false;
            }
            else
            {
                messageReceiver = blks[0] as IMyTextPanel;
                messageReceiver.WritePublicTitle("");
                messageReceiver.WritePrivateTitle("NAV");
            }

            if (WANProgram == null)
            {
                Echo("Error: Can't find programming block for Wico Area Network");
                all_blocks_found = false;
            }

            if (lcdPanel == null)
            {
                Echo("Error: Expect 1 LCD");
                all_blocks_found = false;
            }

            if (!IS_PLANET && connector == null)
            {
                Echo("Error: Can't find any connectors to use for docking");
                all_blocks_found = false;
            }

            if (!IS_BASE && remoteControl == null)
            {
                Echo("Error: Can't find any remote control blocks");
                all_blocks_found = false;
            }

            if (!IS_PLANET && door == null)
            {
                Echo("Error: Can't find door");
                all_blocks_found = false;
            }

            if (!IS_BASE && gyros.Count == 0)
            {
                Echo("Error: No gyros detected");
                all_blocks_found = false;
            }

            if (!IS_BASE && timer == null)
            {
                Echo("Error: No timer found");
                all_blocks_found = false;
            }
            if (IS_PLANET && landLight == null)
            {
                Echo("Error: No light for landing ship destination found");
                all_blocks_found = false;
            }
            if (!IS_BASE && gears.Count == 0)
            {
                Echo("Warning: no landing gear found.  You will not be able to land on planets");
            }

            // Init communicator state machine
            comm = communicate().GetEnumerator();

            // Clear autopilot state machine
            fly = null;
            #endregion
        }
예제 #33
0
파일: rev4a.cs 프로젝트: KamuiXenom/spas
	void Main() {
		// get a list of all blocks in the grid terminal system
		List<IMyTerminalBlock> blocks = new List<IMyTerminalBlock>();
		GridTerminalSystem.GetBlocks(blocks);

		// initialize the reference solar panel if it hasn't been initialized yet
		if (referencePanel == null) {
			// search all available blocks for one containing the reference panel name
			for (int i = 0; i < blocks.Count; i++) {
				if (blocks[i].CustomName.Contains(referencePanelName)) {
					referencePanel = blocks[i] as IMySolarPanel;
					if (referencePanel != null) break;
				}
			}
			if (referencePanel == null) throw new Exception(" Main(): failed to find solar panel with name '" + referencePanelName + "'");
		}

		// initialize the timer if it hasn't been initialized yet
		if (timer == null) {
			// search all available blocks for one containing the timer name
			for (int i = 0; i < blocks.Count; i++) {
				if (blocks[i].CustomName.Contains(timerName)) {
					timer = blocks[i] as IMyTimerBlock;
					if (timer != null)
						break;
				}
			}
			if (timer == null) throw new Exception(" Main(): failed to find timer block with name '" + timerName + "'");
		}

		// initialize the rotors list if no rotors have been registered yet
		if (rotors.Count <= 0) {
			for (int i = 0; i < rotorNames.Length; i++) {
				IMyTerminalBlock rotor = GridTerminalSystem.GetBlockWithName(rotorNames[i]);

				// only add rotors that actually exist and haven't been added yet
				if (rotor != null && !rotors.Contains(rotor)) {
					rotors.Add(rotor);
					rotor.SetValue("Velocity", rotorSpeed);
					ToggleOff(rotor);
				}
			}
			if (rotors.Count <= 0) throw new Exception(" Main(): failed to find any rotors with the specified names");
		}

		// rotate the current rotor
		float currentPower;
		if (!MaxOutput(referencePanel, out currentPower)) throw new Exception(" Main(): failed to read current power output from DetailedInfo");
		if (currentPower >= targetPowerOutput) {
			for (int i = 0; i < rotors.Count; i++) {
				ToggleOff(rotors[i]);
			}
			UpdateName(referencePanel);
			TriggerTimerIdle();
			return;
		}
		if (currentRotor == null) {
			currentRotor = rotors[currentIndex] as IMyMotorStator;
			updatedRotor = true;
		}
		if (currentRotor == null) throw new Exception(" Main(): block '" + rotors[currentIndex].CustomName + "' is not a rotor but was registered as rotor to use");

		if (updatedRotor) {
			if (!testingDirection) {
				// set the best rotation direction
				UpdateName(referencePanel);
				ToggleOn(currentRotor);
				testingDirection = true;
				TriggerTimer();
				return;
			}

			ToggleOff(currentRotor);
			float oldPowerWDIHTCT;
			UpdateName(referencePanel, out oldPowerWDIHTCT, out currentPower);
			if (oldPowerWDIHTCT > currentPower) Reverse(currentRotor);
			updatedRotor = false;
			testingDirection = false;
		}

		// get the optimal rotation
		if (!setting) {
			ToggleOn(currentRotor);
			setting = true;
			UpdateName(referencePanel);
			TriggerTimer();
			return;
		}

		float oldPower;
		UpdateName(referencePanel, out oldPower, out currentPower);
		if (oldPower > currentPower) {
			ToggleOff(currentRotor);
			currentRotor = null;
			currentIndex = (currentIndex + 1) % rotors.Count;
		}
		setting = false;
		TriggerTimer();
	}
예제 #34
0
파일: rev7.cs 프로젝트: KamuiXenom/spas
    void InitializeTimer() {
        // exit this method if the timer has already been initialized 
        if (timer != null) return;

        timer = GridTerminalSystem.GetBlockWithName(Configuration.TimerName) as IMyTimerBlock;
        if (timer == null) throw new Exception("InitializeTimer(): failed to find timer block with name \"" + Configuration.TimerName + "\"");

        Echo("initialized timer");
    }
예제 #35
0
파일: rev5.cs 프로젝트: KamuiXenom/spas
	static void TriggerTimer(IMyTimerBlock timer, float delay) {
		timer.SetValue("TriggerDelay", delay);
		timer.GetActionWithName("Start").Apply(timer);
	}
예제 #36
0
파일: rev5.cs 프로젝트: KamuiXenom/spas
	void Main() {
		// initialize the reference solar panel
		if (ReferencePanel == null) {
			// get a list of all available solar panels
			List<IMyTerminalBlock> solarPanels = new List<IMyTerminalBlock>();
			GridTerminalSystem.GetBlocksOfType<IMySolarPanel>(solarPanels);

			// search all available blocks for one containing the reference solar panel's name
			for (int i = 0; i < solarPanels.Count; i++) {
				IMySolarPanel solarPanel = solarPanels[i] as IMySolarPanel;
				if (solarPanel != null && solarPanel.CustomName.StartsWith(Configuration.ReferencePanelName)) {
					ReferencePanel = solarPanel;
					if (ReferencePanel != null) break;
				}
			}
			if (ReferencePanel == null) throw new Exception(" Main(): Failed to find solar panel with name \"" + Configuration.ReferencePanelName + "\"");
		}

		// initialize the timer
		if (Timer == null) {
			Timer = GridTerminalSystem.GetBlockWithName(Configuration.TimerName) as IMyTimerBlock;
			if (Timer == null) throw new Exception(" Main(): Failed to find timer block with name \"" + Configuration.TimerName + "\"");
		}

		// initialize rotors list
		if (Rotors.Count <= 0) {
			for (int i=0; i < Configuration.RotorNames.Length; i++) {
				IMyMotorStator rotor = GridTerminalSystem.GetBlockWithName(Configuration.RotorNames[i]) as IMyMotorStator;

				// only add rotors that exist and haven't been added yet
				if (rotor != null && !Rotors.Contains(rotor)) {
					Rotors.Add(rotor);
					rotor.SetValue("Velocity", Configuration.RotorSpeed);
					ToggleOff(rotor);
				}
			}
			if (Rotors.Count < Configuration.RotorNames.Length) throw new Exception(" Main(): Failed to find all rotors - found " + Rotors.Count + " rotors, " + Configuration.RotorNames.Length + " were specified");
		}

		// rotate the current rotor
		float currentPower;
		if (!MaxOutput(ReferencePanel, out currentPower)) throw new Exception(" Main(): Failed to read maximum power output from the solar panel's information");

		// check if the target power output has been reached
		if (currentPower >= Configuration.TargetPowerOutput) {
			for (int i=0; i < Rotors.Count; i++) {
				ToggleOff(Rotors[i]);
			}
			UpdateName(ReferencePanel);
			TriggerTimerIdle();
			return;
		}

		// update the rotor and test which direction yields the higher power output
		if (CurrentRotor == null || CurrentStatus == Status.UPDATING) {
			CurrentRotor = Rotors[CurrentRotorIndex];
			UpdateName(ReferencePanel);
			ToggleOn(CurrentRotor);
			CurrentStatus = Status.TESTING;
			TriggerTimer();
			return;
		}

		// set the direction towards the higher power output
		if (CurrentStatus == Status.TESTING) {
			ToggleOff(CurrentRotor);
			float oldPower;
			UpdateName(ReferencePanel, out oldPower, out currentPower);
			if (oldPower > currentPower) Reverse(CurrentRotor);
			CurrentStatus = Status.ALIGNING;
		}

		// rotate towards maximum power output
		if (CurrentStatus == Status.ALIGNING) {
			ToggleOn(CurrentRotor);
			UpdateName(ReferencePanel);
			CurrentStatus = Status.CHECKING;
			TriggerTimer();
			return;
		}

		if (CurrentStatus == Status.CHECKING) {
			float oldPower;
			UpdateName(ReferencePanel, out oldPower, out currentPower);
			if (oldPower > currentPower) {
				ToggleOff(CurrentRotor);
				CurrentStatus = Status.UPDATING;
				CurrentRotorIndex = (CurrentRotorIndex + 1) % Rotors.Count;
			}
			TriggerTimer();
			return;
		}
	}