Ejemplo n.º 1
0
            void Control()
            {
                var TargetVecLoc = CustVectorTransform(Controller.GetTotalGravity(), HingeNeck.WorldMatrix.GetOrientation());
                var Roll         = Math.Atan2(-TargetVecLoc.X, TargetVecLoc.Z);
                var Pitch        = Math.Atan2(TargetVecLoc.Y, TargetVecLoc.Z);

                HingeNeck.TargetVelocityRad = Turn(-(float)Roll, HingeNeck.Angle);

                DampSuspRot(RotorSusp);
                foreach (var h in Hinges)
                {
                    DampSuspHinge(h, Roll, Pitch);
                }
            }
Ejemplo n.º 2
0
        public void Main(string argument, UpdateType updateSource)
        {
            if ((updateSource & UpdateType.Trigger) != 0)
            {
                if (argument == "HDamp")
                {
                    hDamp = !hDamp;
                }
                if (argument == "ManualAlt")
                {
                    manualAlt    = !manualAlt;
                    targAltitude = GetAltitude();
                    targSpd      = 0;
                }
                if (argument == "VDamp")
                {
                    vDamp = !vDamp;
                }
                if (argument == "Spd+")
                {
                    SetSpd(curSpeed + 1);
                }
                if (argument == "Spd-")
                {
                    SetSpd(curSpeed - 1);
                }
            }
            bool     trueHDamp = hDamp;
            Vector3D pos       = sc.CenterOfMass;
            Vector3D spd       = sc.GetShipVelocities().LinearVelocity;
            Vector3D grav      = Vector3D.Normalize(sc.GetTotalGravity());
            double   gravNorm  = sc.GetTotalGravity().Length();
            Vector3D gravin    = Vector3D.TransformNormal(grav, MatrixD.Transpose(sc.WorldMatrix));
            Vector3D spdin     = Vector3D.TransformNormal(spd, MatrixD.Transpose(sc.WorldMatrix));
            Vector3D MoveIndic = sc.MoveIndicator;
            Vector3D COM       = PosToShip(sc.CenterOfMass);

            if (gravin.Y > 0)
            {
                hDamp = false;
            }



            //orientation
            if (MoveIndic.X != 0 || MoveIndic.Z != 0)
            {
                trueHDamp = false;
            }
            double inclCommand   = rotAngles[curSpeed];
            double angleToRotSpd = 1.0;

            // new orientation
            lastHeading -= grav * grav.Dot(lastHeading);
            lastHeading.Normalize();
            Vector3D right = grav.Cross(lastHeading);

            right.Normalize();

            lastHeading += 0.001 * right * sc.RotationIndicator.Y;
            lastHeading.Normalize();

            Vector3D ntarget = grav;
            double   targetX = 0.0, targetZ = 0.0;

            if (trueHDamp)
            {
                targetZ = Clamp(-(spdin.Z) * 0.05, -0.5, 0.5);
                targetX = Clamp(-(spdin.X) * 0.05, -0.5, 0.5);
            }
            else
            {
                targetX = inclCommand * MoveIndic.X;
                targetZ = inclCommand * MoveIndic.Z;
            }
            ntarget -= targetX * right;
            ntarget += targetZ * lastHeading;

            ntarget.Normalize();

            Vector3D headtarget = right.Cross(ntarget);

            headtarget.Normalize();

            Vector3D    ntargetin    = Vector3D.TransformNormal(ntarget, MatrixD.Transpose(sc.WorldMatrix));
            Vector3D    headtargetin = Vector3D.TransformNormal(headtarget, MatrixD.Transpose(sc.WorldMatrix));
            QuaternionD targq        = QuaternionD.CreateFromForwardUp(headtargetin, -ntargetin);
            Vector3D    axis;
            double      angle;

            targq.GetAxisAngle(out axis, out angle);
            axis *= angle;
            axis *= angleToRotSpd;
            SetRotSpd(axis);



            // new altitude
            double curAltitude = GetAltitude();
            double curVSpeed   = (curAltitude - lastAltitude) * 60;
            double targAcc     = 0;

            if (vDamp)
            {
                targAcc = Clamp(-targSpd, -accelerations[curSpeed], accelerations[curSpeed]);
            }
            if (MoveIndic.Y != 0)
            {
                targAcc = MoveIndic.Y * accelerations[curSpeed];
            }
            targSpd      += targAcc / 60;
            targSpd       = Clamp(targSpd, curVSpeed - maxSpdDrift, curVSpeed + maxSpdDrift);
            targAltitude += targSpd / 60;
            targAltitude  = Clamp(targAltitude, curAltitude - maxAltDrift, curAltitude + maxAltDrift);
            double compTargSpd = targSpd + (targAltitude - curAltitude);
            double compTargAcc = targAcc + gravNorm / (-gravin.Y) + (compTargSpd - curVSpeed);

            if (manualAlt)
            {
                ClearThrust();
            }
            else
            {
                SetThrust(compTargAcc * mass);
            }
            if (tick >= 10)
            {
                tick = 0;

                /*lcd.WriteText($@"grav X={gravin.X:F3} Y={gravin.Y:F3} Z={gravin.Z:F3}
                 * Spd X={spdin.X:F3} Y={spdin.Y:F3} Z={spdin.Z:F3}
                 * AA X={axis.X:F3} Y={axis.Y:F3} Z={axis.Z:F3}
                 * NT {ntargetin} {headtargetin}
                 * hDamp {hDamp} vDamp {vDamp} ManualAlt {manualAlt}
                 * Spd: {speedNames[curSpeed]}
                 * Alt cur {curAltitude:F3} targ {targAltitude:F3}
                 * Spd cur {curVSpeed:F10} targ {targSpd:F10} ctarg {compTargSpd:F10}
                 * Acc targ {targAcc:F10} ctarg {compTargAcc:F10}
                 * pos {sc.GetPosition()} scal {Vector3D.Dot(grav, sc.GetPosition())}
                 * cam X {COM.X:F3} Y {COM.Y:F3} Z {COM.Z:F3}
                 * th back {backT:F3} front {frontT:F3}
                 * dist back {distback:F3} front{distfront:F3}
                 * ");*/

                lcd.WriteText($@"Helico control software
Horizontal Dampeners (4) {OnOff(hDamp)}
Vertical Dampeners (5) {OnOff(vDamp)}
Manual Altitude (6) {OnOff(manualAlt)}
Current Altitude {curAltitude:F2}m
Vertical Speed {targSpd:F2}m/s
Speed mode (^8/v9) {speedNames[curSpeed]}
");
            }
            else
            {
                tick++;
            }



            lastAltitude = curAltitude;
        }
Ejemplo n.º 3
0
            private void UpdateThrusterGroups()
            {
                if (_controller == null)
                {
                    return;
                }
                if (_config.LiftThrustersGroupName != "")
                {
                    _liftThrusters.FindBlocks(true, null, _config.LiftThrustersGroupName);
                }
                else
                {
                    _liftThrusters.FindBlocks(true, thruster => {
                        Vector3D thrusterDirection = -thruster.WorldMatrix.Forward;
                        //double forwardDot = Vector3D.Dot(thrusterDirection, _controller.WorldMatrix.Forward);
                        double upDot = Vector3D.Dot(thrusterDirection, -Vector3.Normalize(_controller.GetTotalGravity()));
                        //double leftDot = Vector3D.Dot(thrusterDirection, _controller.WorldMatrix.Left);

                        if (upDot >= 0.2)
                        {
                            return(true);
                        }
                        return(false);
                    });
                }
                if (_config.StopThrustersGroupName != "")
                {
                    _stopThrusters.FindBlocks(true, null, _config.StopThrustersGroupName);
                }
                else
                {
                    _stopThrusters.FindBlocks(true, thruster => {
                        Vector3D thrusterDirection = -thruster.WorldMatrix.Forward;
                        double forwardDot          = Vector3D.Dot(thrusterDirection, _controller.GetShipVelocities().LinearVelocity);
                        //double upDot = Vector3D.Dot(thrusterDirection, _controller.WorldMatrix.Up);
                        //double leftDot = Vector3D.Dot(thrusterDirection, _controller.WorldMatrix.Left);

                        if (forwardDot <= -0.7)
                        {
                            return(true);
                        }
                        return(false);
                    });
                }
                _cruiseThrusters.FindBlocks(true, thruster => {
                    var facing = thruster.Orientation.TransformDirection(Base6Directions.Direction.Forward);
                    return(facing == Base6Directions.Direction.Backward);
                });
                _cruiseReverseThrusters.FindBlocks(true, thruster => {
                    var facing = thruster.Orientation.TransformDirection(Base6Directions.Direction.Forward);
                    return(facing == Base6Directions.Direction.Forward);
                });
            }
        public void Update(TimeSpan timestamp, UpdateFrequency updateFlags)
        {
            if (timestamp == TimeSpan.Zero)
            {
                return;
            }
            foreach (var bird in Hummingbirds)
            {
                if (bird.IsAlive())
                {
                    bird.Update();
                }
                else
                {
                    DeadBirds.Add(bird);
                }
            }

            foreach (var bird in DeadBirds)
            {
                DeregisterBird(bird);
            }

            runs++;
            if (runs % 20 == 0)
            {
                var intelItems = IntelProvider.GetFleetIntelligences(timestamp);

                // Get the top targets
                TopEnemies.Clear();
                EnemyToScore.Clear();

                foreach (var intelItem in intelItems)
                {
                    if (intelItem.Key.Item1 == IntelItemType.Enemy)
                    {
                        var esi  = (EnemyShipIntel)intelItem.Value;
                        var dist = (esi.GetPositionFromCanonicalTime(timestamp + IntelProvider.CanonicalTimeDiff) - Context.Reference.WorldMatrix.Translation).Length();
                        if (dist > MaxEngagementDist)
                        {
                            continue;
                        }

                        var priority = IntelProvider.GetPriority(esi.ID);
                        var size     = esi.Radius;

                        if (size < MinEngagementSize && priority < 3)
                        {
                            continue;
                        }

                        if (priority < 2)
                        {
                            continue;
                        }

                        int score = (int)(priority * 10000 + size);

                        EnemyToScore[esi] = score;

                        for (int i = 0; i <= TopEnemies.Count; i++)
                        {
                            if (i == TopEnemies.Count || score > EnemyToScore[TopEnemies[i]])
                            {
                                TopEnemies.Insert(i, esi);
                                break;
                            }
                        }
                    }
                }

                // Determine how many birds should be assigned to each enemy
                EnemyToNumBirds.Clear();

                int totalNeededBirds = 0;

                for (int i = 0; i < TopEnemies.Count && i < 4; i++)
                {
                    EnemyToNumBirds[TopEnemies[i]]      = EnemyCountToNumBirdsPerEnemy[TopEnemies.Count][i];
                    EnemyToAssignedBirds[TopEnemies[i]] = 0;
                    totalNeededBirds += EnemyToNumBirds[TopEnemies[i]];
                }

                // Remove excess birds from enemies
                foreach (var bird in Hummingbirds)
                {
                    var birdTargetID = BirdToEnemy[bird];
                    if (birdTargetID == 0)
                    {
                        continue;
                    }

                    if (!bird.IsCombatCapable())
                    {
                        BirdToEnemy[bird] = 0;
                        continue;
                    }

                    var birdTargetKey = MyTuple.Create(IntelItemType.Enemy, birdTargetID);
                    if (!intelItems.ContainsKey(birdTargetKey))
                    {
                        BirdToEnemy[bird] = 0;
                        continue;
                    }

                    var birdTarget = (EnemyShipIntel)intelItems[birdTargetKey];
                    if (!EnemyToNumBirds.ContainsKey(birdTarget) || EnemyToNumBirds[birdTarget] == 0)
                    {
                        BirdToEnemy[bird] = 0;
                        continue;
                    }

                    EnemyToNumBirds[birdTarget]--;
                    totalNeededBirds--;
                }

                // Assign birds to enemies
                foreach (var bird in Hummingbirds)
                {
                    if (totalNeededBirds == 0)
                    {
                        break;
                    }

                    // Bird can't fight, keep looking
                    if (!bird.IsCombatCapable())
                    {
                        continue;
                    }

                    // Bird already has target, keep looking
                    if (BirdToEnemy[bird] != 0)
                    {
                        continue;
                    }

                    EnemyShipIntel targetEnemy = null;
                    foreach (var enemy in EnemyToNumBirds.Keys)
                    {
                        if (EnemyToNumBirds[enemy] > 0)
                        {
                            targetEnemy = enemy;
                            break;
                        }
                    }

                    BirdToEnemy[bird] = targetEnemy.ID;
                    EnemyToNumBirds[targetEnemy]--;
                    totalNeededBirds--;
                }

                NeedsMoreBirds = totalNeededBirds > 0;
                int birdIndex;

                // ASSUME birds are not far enough from main controller that gravity direction matters too much
                var gravDir = Controller.GetTotalGravity();
                gravDir.Normalize();

                // For each enemy, assign bird target and destination
                foreach (var enemy in TopEnemies)
                {
                    birdIndex = 0;
                    foreach (var bird in Hummingbirds)
                    {
                        if (BirdToEnemy[bird] != enemy.ID)
                        {
                            continue;
                        }

                        if (bird.Gats.Count == 0)
                        {
                            continue;
                        }
                        var birdAltitudeTheta = Math.PI * ((runs / (BirdSineConstantSeconds * 30) % 2) - 1);
                        var birdSwayTheta     = Math.PI * ((runs / (BirdPendulumConstantSeconds * 30) % 2) - 1);
                        var targetPos         = enemy.GetPositionFromCanonicalTime(timestamp + IntelProvider.CanonicalTimeDiff);

                        bird.SetTarget(targetPos, enemy.GetVelocity() - gravDir * (float)TrigHelpers.FastCos(birdAltitudeTheta) * 2);

                        var targetToBase = bird.Base.WorldMatrix.Translation - targetPos;
                        targetToBase -= VectorHelpers.VectorProjection(targetToBase, gravDir);
                        var targetToBaseDist = targetToBase.Length();
                        targetToBase.Normalize();

                        var engageLocationLocus    = targetToBase * Math.Min(600, targetToBaseDist + 400) + targetPos;
                        var engageLocationSwayDir  = targetToBase.Cross(gravDir);
                        var engageLocationSwayDist = (TrigHelpers.FastCos(birdSwayTheta) - EnemyToAssignedBirds[enemy] * 0.5 + birdIndex + 0.5) * 100;

                        bird.SetDest(engageLocationLocus + engageLocationSwayDist * engageLocationSwayDir);

                        var birdDir = bird.Controller.WorldMatrix.Translation - Controller.WorldMatrix.Translation;
                        birdDir -= VectorHelpers.VectorProjection(birdDir, gravDir);;
                        var birdDist = birdDir.Length();

                        bird.Drive.DesiredAltitude = birdDist < 100 ? Hummingbird.RecommendedServiceCeiling :
                                                     (float)TrigHelpers.FastSin(birdAltitudeTheta + Math.PI * 0.5) *
                                                     (Hummingbird.RecommendedServiceCeiling - Hummingbird.RecommendedServiceFloor) + Hummingbird.RecommendedServiceFloor;

                        birdIndex++;
                    }
                }

                // Assign orbit task for unassigned birds
                int numReserveBirds = 0;
                foreach (var bird in Hummingbirds)
                {
                    if (BirdToEnemy[bird] == 0 && bird.IsCombatCapable())
                    {
                        numReserveBirds++;
                    }
                }
                birdIndex = 0;
                var randomPoint = new Vector3D(190, 2862, 809);
                randomPoint -= VectorHelpers.VectorProjection(randomPoint, gravDir);
                randomPoint.Normalize();

                var randomPointCross = randomPoint.Cross(gravDir);

                foreach (var bird in Hummingbirds)
                {
                    if (BirdToEnemy[bird] != 0)
                    {
                        continue;
                    }
                    bird.SetTarget(Vector3D.Zero, Vector3D.Zero);
                    bird.Drive.DesiredAltitude = 30;

                    if (bird.IsCombatCapable() && !bird.IsRetiring)
                    {
                        var birdOrbitTheta = Math.PI * (((2 * birdIndex / (float)numReserveBirds) + runs / (BirdOrbitSeconds * 30)) % 2 - 1);

                        var birdOrbitDest = Controller.WorldMatrix.Translation +
                                            TrigHelpers.FastCos(birdOrbitTheta) * randomPoint * BirdOrbitDist +
                                            TrigHelpers.FastSin(birdOrbitTheta) * randomPointCross * BirdOrbitDist;

                        bird.SetDest(birdOrbitDest);

                        birdIndex++;
                    }
                    else if (!bird.IsRetiring)
                    {
                        RetireBird(bird);
                    }
                    else if (bird.IsRetiring)
                    {
                        if (!bird.IsLanding)
                        {
                            var birdDir = bird.Controller.WorldMatrix.Translation - bird.Destination;
                            birdDir -= VectorHelpers.VectorProjection(birdDir, gravDir);
                            var birdDist = birdDir.Length();
                            birdDir.Normalize();

                            if (birdDist < 50)
                            {
                                bird.SetDest(Vector3D.Zero);
                                bird.Drive.Flush();
                                foreach (var engine in bird.Drive.HoverEngines)
                                {
                                    engine.AltitudeMin = 0;
                                }
                                bird.IsLanding = true;
                            }
                        }
                        else
                        {
                            double altitude;
                            bird.Controller.TryGetPlanetElevation(MyPlanetElevation.Surface, out altitude);
                            if (altitude < 6)
                            {
                                foreach (var engine in bird.Drive.HoverEngines)
                                {
                                    engine.Block.Enabled = false;
                                    DeadBirds.Add(bird);
                                }
                            }
                        }
                    }
                }
            }

            foreach (var cradle in Cradles)
            {
                if (cradle == null)
                {
                    continue;
                }
                cradle.Update();
            }

            if (runs % 60 == 0)
            {
                BirdReleaseTimeout--;
                for (int i = 0; i < Cradles.Count(); i++)
                {
                    if (Cradles[i] == null)
                    {
                        continue;
                    }
                    if (Cradles[i].Hummingbird == null)
                    {
                        Cradles[i].CheckHummingbird();
                    }
                    else if (NeedsMoreBirds && BirdReleaseTimeout <= 0)
                    {
                        Hummingbird bird = Cradles[i].Release();
                        bird.Base = Context.Reference;
                        RegisterBird(bird);
                        BirdReleaseTimeout = 5;
                    }
                }
            }

            DeadBirds.Clear();
        }