Esempio n. 1
0
            public override bool Update(AutoPilot owner, ref Vector3D linearV, ref Vector3D angularV)
            {
                if (Goal == null)
                {
                    return(false);
                }
                IMyCubeBlock reference = Reference ?? owner.Controller;
                MatrixD      wm        = reference.WorldMatrix;

                Goal.UpdateTime(owner.elapsedTime);
                Vector3D currentGoalPos  = Goal.CurrentPosition;
                Vector3D direction       = currentGoalPos - wm.Translation;
                double   distance        = direction.Normalize();
                double   target_distance = distance;
                double   diff;

                if (!Vector3D.IsZero(Approach))
                {
                    Vector3D minusApproach = -Approach;
                    diff = owner.RotateToMatch(Approach, Facing,
                                               wm.GetDirectionVector(ReferenceForward),
                                               wm.GetDirectionVector(ReferenceUp),
                                               ref angularV);
                    PlaneD   alignment  = new PlaneD(wm.Translation, minusApproach);
                    Vector3D alignedPos = alignment.Intersection(ref currentGoalPos, ref minusApproach);
                    Vector3D correction = alignedPos - wm.Translation;
                    if (!Vector3D.IsZero(correction, PositionEpsilon)) //are we on approach vector?
                    {                                                  //no - let's move there
                        direction = correction;
                        distance  = direction.Normalize();
                    }
                    //otherwise, we can keep our current direction
                }
                else
                {
                    diff = owner.RotateToMatch(direction, Facing,
                                               wm.GetDirectionVector(ReferenceForward),
                                               wm.GetDirectionVector(ReferenceUp),
                                               ref angularV);
                }
                //rotate the ship to face it
                if (diff > OrientationEpsilon) //we still need to rotate
                {
                    linearV = Goal.Velocity;   //match velocities with our target, then.
                }
                else //we are good
                {
                    //how quickly can we go, assuming we still need to stop at the end?
                    double accel               = owner.GetMaxAccelerationFor(-direction);
                    double braking_time        = Math.Sqrt(2 * distance / accel);
                    double acceptable_velocity = Math.Min(VelocityUsage * accel * braking_time, MaxLinearSpeed);
                    //extra slowdown when close to the target
                    acceptable_velocity = Math.Min(acceptable_velocity, distance);
                    //moving relative to the target
                    linearV  = direction * acceptable_velocity + Goal.Velocity;
                    angularV = Vector3D.Zero;
                }
                return(TryLockIn(distance) || (target_distance < PositionEpsilon));
            }
            public override bool Update(AutoPilot owner, ref Vector3D linearV, ref Vector3D angularV)
            {
                if (Goal == null)
                {
                    return(false);
                }
                IMyCubeBlock reference = Reference ?? owner.Controller;
                MatrixD      wm        = reference.WorldMatrix;

                Goal.UpdateTime(owner.elapsedTime);
                Vector3D direction = Goal.CurrentPosition - wm.Translation;
                double   distance  = direction.Normalize();

                //linear velocity
                linearV = direction * MaxLinearSpeed + Goal.Velocity;
                //angular velocity
                double diff = owner.RotateToMatch(direction, Vector3D.Zero,
                                                  wm.GetDirectionVector(ReferenceForward),
                                                  wm.GetDirectionVector(ReferenceUp),
                                                  ref angularV);

                if (diff < OrientationEpsilon)
                {
                    angularV = Vector3D.Zero;
                }
                return((diff < OrientationEpsilon) && (distance < PositionEpsilon));
            }
Esempio n. 3
0
            /// <summary>
            /// Queries the strategy on which linear and angular velocities the ship should have.
            /// </summary>
            /// <param name="owner">AutoPilot instance that queries the strategy.</param>
            /// <param name="linearV">Initial value - current linear velocity. Is set to desired linear velocity.</param>
            /// <param name="angularV">Initial value - current rotation. Is set to desired rotation.</param>
            /// <returns>True if goal is considered achieved.</returns>
            public override bool Update(AutoPilot owner, ref Vector3D linearV, ref Vector3D angularV)
            {
                if (Goal == null)
                {
                    return(false);
                }
                IMyCubeBlock reference = Reference ?? owner.Controller;
                Vector3D     pos       = Goal.CurrentPosition;
                MatrixD      wm        = reference.WorldMatrix;
                Vector3D     direction = pos - wm.Translation;
                double       distance  = direction.Normalize();

                linearV.X = linearV.Y = linearV.Z = 0;
                double diff = owner.RotateToMatch(direction, Vector3D.Zero,
                                                  wm.GetDirectionVector(ReferenceForward),
                                                  wm.GetDirectionVector(ReferenceUp),
                                                  ref angularV);

                if (diff < OrientationEpsilon)
                {
                    angularV = Vector3D.Zero;
                    return(true);
                }
                else
                {
                    return(false);
                }
            }
Esempio n. 4
0
            /// <summary>
            /// Queries the strategy on which linear and angular velocities the ship should have.
            /// </summary>
            /// <param name="owner">AutoPilot instance that queries the strategy.</param>
            /// <param name="linearV">Initial value - current linear velocity. Is set to desired linear velocity.</param>
            /// <param name="angularV">Initial value - current rotation. Is set to desired rotation.</param>
            /// <returns>True if goal is considered achieved.</returns>
            public override bool Update(AutoPilot owner, ref Vector3D linearV, ref Vector3D angularV)
            {
                if (Goal == null)
                {
                    return(false);
                }
                bool         distanceok    = false;
                bool         orientationok = false;
                IMyCubeBlock reference     = Reference ?? owner.Controller;
                MatrixD      wm            = reference.WorldMatrix;

                Goal.UpdateTime(owner.elapsedTime);
                Vector3D direction       = Goal.CurrentPosition - wm.Translation;
                double   distance        = direction.Normalize();
                Vector3D facingdirection = direction; //we should face our goal, still.

                if (distance < Goal.TargetDistance)   //Are we too close to the goal?
                {                                     // yep! better back off.
                    direction *= -1;
                    distance   = Goal.TargetDistance - distance;
                }
                else //nah, we aren't there yet - just cut the distance we need to travel.
                {
                    distance -= Goal.TargetDistance;
                }
                if (distance > PositionEpsilon) //Are we too far from our desired position?
                {
                    //rotate the ship to face it
                    double diff = owner.RotateToMatch(facingdirection, Vector3D.Zero,
                                                      wm.GetDirectionVector(ReferenceForward),
                                                      wm.GetDirectionVector(ReferenceUp),
                                                      ref angularV);
                    if (diff > OrientationEpsilon) //we still need to rotate
                    {
                        linearV = Goal.Velocity;   //match velocities with our target, then.
                    }
                    else //we are good
                    {
                        orientationok = true;
                        //how quickly can we go, assuming we still need to stop at the end?
                        double accel               = owner.GetMaxAccelerationFor(-direction);
                        double braking_time        = Math.Sqrt(2 * distance / accel);
                        double acceptable_velocity = Math.Min(VelocityUsage * accel * braking_time, MaxLinearSpeed);
                        //extra slowdown when close to the target
                        acceptable_velocity = Math.Min(acceptable_velocity, distance);
                        //moving relative to the target
                        linearV  = direction * acceptable_velocity + Goal.Velocity;
                        angularV = Vector3D.Zero;
                    }
                }
                else //we are close to our ideal position - attempting to rotate the ship is not a good idea.
                {
                    distanceok    = true;
                    orientationok = true;
                    linearV       = Goal.Velocity;
                    angularV      = Vector3D.Zero;
                }
                return(distanceok && orientationok);
            }
Esempio n. 5
0
            /// <summary>
            /// Queries the strategy on which linear and angular velocities the ship should have.
            /// </summary>
            /// <param name="owner">AutoPilot instance that queries the strategy.</param>
            /// <param name="linearV">Initial value - current linear velocity. Is set to desired linear velocity.</param>
            /// <param name="angularV">Initial value - current rotation. Is set to desired rotation.</param>
            /// <returns>False, since orbiter has no goal to achieve.</returns>
            public override bool Update(AutoPilot owner, ref Vector3D linearV, ref Vector3D angularV)
            {
                if (Goal == null)
                {
                    return(false);
                }
                IMyCubeBlock reference = Reference ?? owner.Controller;
                MatrixD      wm        = reference.WorldMatrix;
                Vector3D     radius    = Goal.CurrentPosition - wm.Translation;
                double       R         = radius.Normalize();
                Vector3D     vel       = Normal.Cross(radius);

                vel.Normalize();
                linearV = Goal.Velocity + vel * MaxLinearSpeed + radius * (R - Goal.TargetDistance);
                double diff = owner.RotateToMatch(radius, Normal,
                                                  wm.GetDirectionVector(ReferenceForward),
                                                  wm.GetDirectionVector(ReferenceUp),
                                                  ref angularV);

                return(false);
            }