Ejemplo n.º 1
0
        private double FindAngle(PointF first, PointF second)
        {
            double angle = Math.Atan2(second.Y - first.Y, second.X - first.X);

            return(XeroUtils.BoundDegrees(XeroUtils.RadiansToDegrees(angle) - 90.0));
        }
Ejemplo n.º 2
0
        public override Dictionary <string, PathSegment[]> ModifyPath(RobotParams robot, RobotPath path, PathSegment[] segs, double rotvel)
        {
            Dictionary <string, PathSegment[]> result = new Dictionary <string, PathSegment[]>();

            if (segs == null)
            {
                return(null);
            }

            double             total   = segs[segs.Length - 1].GetValue("time");
            double             rtime   = total - path.FacingAngleStartDelay - path.FacingAngleEndDelay;
            TrapezoidalProfile profile = CreateRotationProfile(robot, path.StartFacingAngle, path.EndFacingAngle, rtime, rotvel);

            if (profile == null)
            {
                throw new DriveModifier.VelocitySplitException();
            }

            PathSegment[] fl = new PathSegment[segs.Length];
            PathSegment[] fr = new PathSegment[segs.Length];
            PathSegment[] bl = new PathSegment[segs.Length];
            PathSegment[] br = new PathSegment[segs.Length];

            result["fl"] = fl;
            result["fr"] = fr;
            result["bl"] = bl;
            result["br"] = br;

            for (int i = 0; i < segs.Length; i++)
            {
                //
                // The time in the path
                //
                double time = segs[i].GetValue("time");

                //
                // The current facing angle based on the rotational trapezoidal profile
                //
                double current = XeroUtils.BoundDegrees(path.StartFacingAngle + profile.GetDistance(time - path.FacingAngleStartDelay));

                //
                // Get the required velocity to perform the rotation.  This is the
                // linear ground based velocity for the wheel that must be applied to
                // each wheel in direction perpendicular to the vector from the center of
                // the robot to the center of the wheel.
                //
                double rv = RotationalToGround(robot, profile.GetVelocity(time - path.FacingAngleStartDelay));
                double ra = RotationalToGround(robot, profile.GetAcceleration(time - path.FacingAngleStartDelay));

                //
                // Get the velocity vector and acceleration vector relative to each of the
                // wheels to rotate the robot based on the desired rotational velocity.
                //
                XeroVector rotflvel = GetWheelPerpendicularVector(robot, Wheel.FL, rv);
                XeroVector rotfrvel = GetWheelPerpendicularVector(robot, Wheel.FR, rv);
                XeroVector rotblvel = GetWheelPerpendicularVector(robot, Wheel.BL, rv);
                XeroVector rotbrvel = GetWheelPerpendicularVector(robot, Wheel.BR, rv);

                XeroVector rotflacc = GetWheelPerpendicularVector(robot, Wheel.FL, ra);
                XeroVector rotfracc = GetWheelPerpendicularVector(robot, Wheel.FR, ra);
                XeroVector rotblacc = GetWheelPerpendicularVector(robot, Wheel.BL, ra);
                XeroVector rotbracc = GetWheelPerpendicularVector(robot, Wheel.BR, ra);

                //
                // Get the translational velocity vector to follow the path
                //
                XeroVector pathvel = XeroVector.FromDegreesMagnitude(segs[i].GetValue("heading"), segs[i].GetValue("velocity")).RotateDegrees(-current);
                XeroVector pathacc = XeroVector.FromDegreesMagnitude(segs[i].GetValue("heading"), segs[i].GetValue("acceleration")).RotateDegrees(-current);



                //
                // For each wheel, the velocity vector is the sum of the rotational vector and the translational vector
                //
                XeroVector flv = rotflvel + pathvel;
                XeroVector frv = rotfrvel + pathvel;
                XeroVector blv = rotblvel + pathvel;
                XeroVector brv = rotbrvel + pathvel;
                XeroVector fla = rotflacc + pathvel;
                XeroVector fra = rotfracc + pathvel;
                XeroVector bla = rotblacc + pathvel;
                XeroVector bra = rotbracc + pathvel;

                //
                // Now calculate the wheel positions based on the path position and the
                // facing angle
                //
                XeroVector flpos = new XeroVector(robot.Length / 2.0, robot.Width / 2.0).RotateDegrees(current).Translate(segs[i].GetValue("x"), segs[i].GetValue("y"));
                XeroVector frpos = new XeroVector(robot.Length / 2.0, -robot.Width / 2.0).RotateDegrees(current).Translate(segs[i].GetValue("x"), segs[i].GetValue("y"));
                XeroVector blpos = new XeroVector(-robot.Length / 2.0, robot.Width / 2.0).RotateDegrees(current).Translate(segs[i].GetValue("x"), segs[i].GetValue("y"));
                XeroVector brpos = new XeroVector(-robot.Length / 2.0, -robot.Width / 2.0).RotateDegrees(current).Translate(segs[i].GetValue("x"), segs[i].GetValue("y"));

                PathSegment newseg = new PathSegment(segs[i]);
                newseg.SetValue("x", flpos.X);
                newseg.SetValue("y", flpos.Y);
                newseg.SetValue("velocity", flv.Magnitude());
                newseg.SetValue("heading", flv.AngleDegrees());
                newseg.SetValue("acceleration", fla.Magnitude());
                fl[i] = newseg;

                newseg = new PathSegment(segs[i]);
                newseg.SetValue("x", frpos.X);
                newseg.SetValue("y", frpos.Y);
                newseg.SetValue("velocity", frv.Magnitude());
                newseg.SetValue("heading", frv.AngleDegrees());
                newseg.SetValue("acceleration", fra.Magnitude());
                fr[i] = newseg;

                newseg = new PathSegment(segs[i]);
                newseg.SetValue("x", blpos.X);
                newseg.SetValue("y", blpos.Y);
                newseg.SetValue("velocity", blv.Magnitude());
                newseg.SetValue("heading", blv.AngleDegrees());
                newseg.SetValue("acceleration", bla.Magnitude());
                bl[i] = newseg;

                newseg = new PathSegment(segs[i]);
                newseg.SetValue("x", brpos.X);
                newseg.SetValue("y", brpos.Y);
                newseg.SetValue("velocity", brv.Magnitude());
                newseg.SetValue("heading", brv.AngleDegrees());
                newseg.SetValue("acceleration", bra.Magnitude());
                br[i] = newseg;
            }

            return(result);
        }