示例#1
0
        public float DistanceTo(Ets2Point pt)
        {
            if (pt == null) return float.MaxValue;
            var dx = pt.X - X;
            var dy = pt.Z - Z;

            var dst = (float) Math.Sqrt(dx * dx + dy * dy);

            return dst;
        }
示例#2
0
        public Ets2NavigationRoute(Ets2Item start, Ets2Item end, Ets2Point from, Ets2Point to, Ets2Mapper mapper)
        {
            Start = start;
            End = end;
            From = from;
            To = to;
            Mapper = mapper;

            if (Start != End)
            ThreadPool.QueueUserWorkItem(new WaitCallback(FindRoute));
        }
示例#3
0
        public Ets2NavigationRoute(Ets2Item start, Ets2Item end, Ets2Point from, Ets2Point to, Ets2Mapper mapper)
        {
            Start  = start;
            End    = end;
            From   = from;
            To     = to;
            Mapper = mapper;

            if (Start != End)
            {
                ThreadPool.QueueUserWorkItem(new WaitCallback(FindRoute));
            }
        }
示例#4
0
        public float DistanceTo(Ets2Point pt)
        {
            if (pt == null)
            {
                return(float.MaxValue);
            }
            var dx = pt.X - X;
            var dy = pt.Z - Z;

            var dst = (float)Math.Sqrt(dx * dx + dy * dy);

            return(dst);
        }
示例#5
0
        /// <summary>
        /// Generate road curves for a specific lane. The curve is generated with [steps]
        /// nodes and positioned left or right from the road's middle point.
        /// Additionally, each extra lane is shifted 4.5 game units outward.
        /// </summary>
        /// <param name="steps"></param>
        /// <param name="leftlane"></param>
        /// <param name="lane"></param>
        /// <returns></returns>
        public IEnumerable <Ets2Point> GenerateRoadCurve(int steps, bool leftlane, int lane)
        {
            var ps = new Ets2Point[steps];

            var sx = StartNode.X;
            var ex = EndNode.X;
            var sz = StartNode.Z;
            var ez = EndNode.Z;

            if (steps == 2)
            {
                sx += (float)Math.Sin(-StartNode.Yaw) * (leftlane ? -1 : 1) * (RoadLook.Offset + (0.5f + lane) * 4.5f);
                sz += (float)Math.Cos(-StartNode.Yaw) * (leftlane ? -1 : 1) * (RoadLook.Offset + (0.5f + lane) * 4.5f);

                ex += (float)Math.Sin(-EndNode.Yaw) * (leftlane ? -1 : 1) * (RoadLook.Offset + (0.5f + lane) * 4.5f);
                ez += (float)Math.Cos(-EndNode.Yaw) * (leftlane ? -1 : 1) * (RoadLook.Offset + (0.5f + lane) * 4.5f);

                ps[0] = new Ets2Point(sx, 0, sz, StartNode.Yaw);
                ps[1] = new Ets2Point(ex, 0, ez, EndNode.Yaw);
                return(ps);
            }


            var radius = (float)Math.Sqrt((sx - ex) * (sx - ex) + (sz - ez) * (sz - ez));

            var tangentSX = (float)Math.Cos(-StartNode.Yaw) * radius;
            var tangentEX = (float)Math.Cos(-EndNode.Yaw) * radius;
            var tangentSZ = (float)Math.Sin(-StartNode.Yaw) * radius;
            var tangentEZ = (float)Math.Sin(-EndNode.Yaw) * radius;

            for (int k = 0; k < steps; k++)
            {
                var s   = (float)k / (float)(steps - 1);
                var x   = (float)Ets2CurveHelper.Hermite(s, sx, ex, tangentSX, tangentEX);
                var z   = (float)Ets2CurveHelper.Hermite(s, sz, ez, tangentSZ, tangentEZ);
                var tx  = (float)Ets2CurveHelper.HermiteTangent(s, sx, ex, tangentSX, tangentEX);
                var ty  = (float)Ets2CurveHelper.HermiteTangent(s, sz, ez, tangentSZ, tangentEZ);
                var yaw = (float)Math.Atan2(ty, tx);
                x    += (float)Math.Sin(-yaw) * (leftlane ? -1 : 1) * (RoadLook.Offset + (0.5f + lane) * 4.5f);
                z    += (float)Math.Cos(-yaw) * (leftlane ? -1 : 1) * (RoadLook.Offset + (0.5f + lane) * 4.5f);
                ps[k] = new Ets2Point(x, 0, z, yaw);
            }

            return(ps);
        }
示例#6
0
        public IEnumerable <Ets2Point> GeneratePolygonForRoute(Ets2PrefabRoute route, Ets2Node node, int nodeOr)
        {
            List <Ets2Point> p = new List <Ets2Point>();

            if (route == null || route.Route == null)
            {
                return(p);
            }

            /*
             * yaw -= this.Nodes[nodeOr].Yaw;
             * yaw += Math.PI/2;
             */
            var xOr = node.X;
            var yOr = node.Z;
            var yaw = node.Yaw - this.Nodes[nodeOr].Yaw + Math.PI / 2;

            foreach (var curve in route.Route)
            {
                var srx = curve.StartX - this.Nodes[nodeOr].X;
                var erx = curve.EndX - this.Nodes[nodeOr].X;
                var sry = curve.StartZ - this.Nodes[nodeOr].Z;
                var ery = curve.EndZ - this.Nodes[nodeOr].Z;

                var sr = (float)Math.Sqrt(srx * srx + sry * sry);
                var er = (float)Math.Sqrt(erx * erx + ery * ery);

                var ans = yaw - Math.Atan2(sry, srx);
                var ane = yaw - Math.Atan2(ery, erx);

                var sx = xOr - sr * (float)Math.Sin(ans);
                var ex = xOr - er * (float)Math.Sin(ane);
                var sy = yOr - sr * (float)Math.Cos(ans);
                var ey = yOr - er * (float)Math.Cos(ane);
                // tmp
                var ps = new Ets2Point[2];
                ps[0] = new Ets2Point(sx, node.Y, sy, (float)ans);
                ps[1] = new Ets2Point(ex, node.Y, ey, (float)ane);

                p.AddRange(ps);
            }

            return(p);
        }
示例#7
0
        public IEnumerable<Ets2Point> GeneratePolygonForRoute(Ets2PrefabRoute route, Ets2Node node,  int nodeOr)
        {
            List<Ets2Point> p = new List<Ets2Point>();

            if (route == null || route.Route == null)
            return p;

            /*
            yaw -= this.Nodes[nodeOr].Yaw;
            yaw += Math.PI/2;
            */
            var xOr = node.X;
            var yOr = node.Z;
            var yaw = node.Yaw - this.Nodes[nodeOr].Yaw + Math.PI / 2;

            foreach (var curve in route.Route)
            {
                var srx = curve.StartX - this.Nodes[nodeOr].X;
                var erx = curve.EndX - this.Nodes[nodeOr].X;
                var sry = curve.StartZ - this.Nodes[nodeOr].Z;
                var ery = curve.EndZ - this.Nodes[nodeOr].Z;

                var sr = (float) Math.Sqrt(srx*srx + sry*sry);
                var er = (float) Math.Sqrt(erx*erx + ery*ery);

                var ans = yaw - Math.Atan2(sry, srx);
                var ane = yaw - Math.Atan2(ery, erx);

                var sx = xOr - sr*(float) Math.Sin(ans);
                var ex = xOr - er*(float) Math.Sin(ane);
                var sy = yOr - sr*(float) Math.Cos(ans);
                var ey = yOr - er*(float) Math.Cos(ane);
                // tmp
                var ps = new Ets2Point[2];
                ps[0] = new Ets2Point(sx, node.Y, sy,(float) ans);
                ps[1] = new Ets2Point(ex, node.Y, ey, (float)ane);

                p.AddRange(ps);
            }

            return p;
        }
示例#8
0
        private void FindNewSegments(Ets2NavigationRoute route, Ets2Point me)
        {
            if (route == null || route.Segments == null)
                return;
            var segs = new List<Ets2NavigationSegment>();

            var dstLimit = 1250;
            rescan:

            foreach (var seg in route.Segments)
            {
                var dstEntry = seg.Entry.Point.DistanceTo(me) < dstLimit;
                var dstExit = seg.Exit.Point.DistanceTo(me) < dstLimit;

                if (dstEntry || dstExit)
                    segs.Add(seg);
            }
            if (!segs.Any() && dstLimit == 1250)
            {
                dstLimit = 5000;
                goto rescan;
            }
            NearbySegments = segs;
        }
示例#9
0
        public void TickTelemetry(IDataMiner data)
        {
            speed = data.Telemetry.Speed;

            if (true)
            {
                var ets2Tel = (Ets2DataMiner) data;
                var x = ets2Tel.MyTelemetry.Physics.CoordinateX;
                var z = ets2Tel.MyTelemetry.Physics.CoordinateZ;
                var yaw = 2*Math.PI*(ets2Tel.MyTelemetry.Physics.RotationX);
                var lah = 1.5f + ets2Tel.MyTelemetry.Physics.SpeedKmh/100.0f*7.5f;
                x += (float)Math.Sin(yaw)*-lah;
                z += (float)Math.Cos(yaw) * -lah;
                var me = new Ets2Point(x, 0, z, (float)yaw);
                lookPoint = new PointF(x, z);
                // Get map
                var map = Main.LoadedMap;
                var route = dlMap.Route;

                if (map == null || route == null)
                {
                    Active = false;
                    return;
                }

                bool firstTry = true;
                Ets2NavigationSegment activeSegment = default(Ets2NavigationSegment);
                var activeSegmentOption = default(Ets2NavigationSegment.Ets2NavigationSegmentOption);
                float dist = float.MaxValue;

            rescanSegment:
                // Find closest segment
                for (int segI = 0; segI < NearbySegments.Count; segI++)
                {
                    var seg = NearbySegments[segI];
                    if (seg == null)
                        continue;
                    if (!seg.Solutions.Any())
                    {
                        continue;
                    }

                    foreach (var sol in seg.Solutions)
                    {
                        if (sol.HiResPoints == null || !sol.HiResPoints.Any())
                            NearbySegments[segI].GenerateHiRes(sol);

                        var dst = sol.HiResPoints.Min(k => k.DistanceTo(me));
                        if (dist > dst)
                        {
                            dist = dst;
                            activeSegment = NearbySegments[segI];
                            activeSegmentOption = sol;
                        }
                    }

                }
                if (!NearbySegments.Any(k => k != null) || dist > 5)
                {
                    FindNewSegments(route, me);
                    if (firstTry)
                    {
                        firstTry = false;
                        goto rescanSegment;
                    }
                    else
                    {
                        //beep.Play();
                        //Active = false;
                        //return;
                    }
                }

                if (activeSegmentOption == null)
                    return;

                var lineDistanceError = 0.0;
                var angleDistancError = 0.0;

                Ets2Point bestPoint = default(Ets2Point);
                Ets2Point bestPointP1 = default(Ets2Point);
                double bestDistance = double.MaxValue;

                for (var k = 0; k < activeSegmentOption.HiResPoints.Count; k++)
                {
                    var distance = me.DistanceTo(activeSegmentOption.HiResPoints[k]);
                    if (bestDistance > Math.Abs(distance))
                    {
                        bestDistance = Math.Abs(distance);
                        if (k + 1 == activeSegmentOption.HiResPoints.Count)
                        {
                            bestPoint = activeSegmentOption.HiResPoints[k - 1];
                            bestPointP1 = activeSegmentOption.HiResPoints[k];
                        }
                        else
                        {
                            bestPoint = activeSegmentOption.HiResPoints[k];
                            var m = k;
                            do
                            {
                                m++;
                                if (m >= activeSegmentOption.HiResPoints.Count)
                                    break;
                                bestPointP1 = activeSegmentOption.HiResPoints[m];
                            } while (bestPoint.DistanceTo(bestPointP1) < 0.1f && m + 1 < activeSegmentOption.HiResPoints.Count);
                        }
                    }
                }
                var min = activeSegmentOption.HiResPoints.Min(k => k.DistanceTo(me));
                if (bestPoint == null)
                    return;

                var lx1 = bestPoint.X - Math.Sin(-bestPoint.Heading) * 5;
                var lz1 = bestPoint.Z - Math.Cos(-bestPoint.Heading) * 5;
                var lx2 = bestPoint.X + Math.Sin(-bestPoint.Heading) * 5;
                var lz2 = bestPoint.Z + Math.Cos(-bestPoint.Heading) * 5;

                lx2 = bestPoint.X;
                lx1 = bestPointP1.X;
                lz2 = bestPoint.Z;
                lz1 = bestPointP1.Z;

                var px1 = me.X - lx1;
                var pz1 = me.Z - lz1;
                var px2 = lz2 - lz1;
                var pz2 = -(lx2 - lx1);
                var qwer = Math.Sqrt(px2*px2 + pz2*pz2);
                Console.WriteLine(qwer);
                // Reference to top (otherwise 90deg offset) - CCW
                yawRoad = activeSegment.Type == Ets2NavigationSegmentType.Road ? -bestPoint.Heading + Math.PI/2 : bestPoint.Heading - Math.PI/2;

                hook = bestPoint;
                lineDistanceError = (px1*px2 + pz1*pz2)/Math.Sqrt(px2*px2 + pz2*pz2);
                angleDistancError = yaw - yawRoad;
                angleDistancError = angleDistancError%(Math.PI*2);
                 //lineDistanceError = -lineDistanceError;
                if (lineDistanceError > 7) lineDistanceError = 7;
                if (lineDistanceError < -7) lineDistanceError = -7;
                //if (Math.Abs(angleDistancError) < Math.PI/4) lineDistanceError = -lineDistanceError;
                Console.WriteLine(lineDistanceError.ToString("0.00m") + " | " + angleDistancError.ToString("0.000rad"));

                var gain = 2.5f + ets2Tel.Telemetry.Speed/2.5f;

                SteerAngle = 0.5f - lineDistanceError/gain;// - angleDistancError * 0.1f;
                //Debug.WriteLine(lineDistanceError + "px error / " + angleDistancError + " angle error / " + SteerAngle);
            }
        }
示例#10
0
 public bool CloseTo(Ets2Point pt)
 {
     return DistanceTo(pt) <= 2f;
 }
示例#11
0
        /// <summary>
        /// Generate road curves for a specific lane. The curve is generated with [steps] 
        /// nodes and positioned left or right from the road's middle point.
        /// Additionally, each extra lane is shifted 4.5 game units outward.
        /// </summary>
        /// <param name="steps"></param>
        /// <param name="leftlane"></param>
        /// <param name="lane"></param>
        /// <returns></returns>
        public IEnumerable<Ets2Point> GenerateRoadCurve(int steps, bool leftlane, int lane)
        {
            var ps = new Ets2Point[steps];

            var sx = StartNode.X;
            var ex = EndNode.X;
            var sz = StartNode.Z;
            var ez = EndNode.Z;

            if (steps == 2)
            {
                sx += (float)Math.Sin(-StartNode.Yaw) * (leftlane ? -1 : 1) * (RoadLook.Offset + (0.5f + lane) * 4.5f);
                sz += (float)Math.Cos(-StartNode.Yaw) * (leftlane ? -1 : 1) * (RoadLook.Offset + (0.5f + lane) * 4.5f);

                ex += (float)Math.Sin(-EndNode.Yaw) * (leftlane ? -1 : 1) * (RoadLook.Offset + (0.5f + lane) * 4.5f);
                ez += (float)Math.Cos(-EndNode.Yaw) * (leftlane ? -1 : 1) * (RoadLook.Offset + (0.5f + lane) * 4.5f);

                ps[0] = new Ets2Point(sx, 0, sz, StartNode.Yaw);
                ps[1] = new Ets2Point(ex, 0, ez, EndNode.Yaw);
                return ps;
            }

            var radius = (float)Math.Sqrt((sx - ex) * (sx - ex) + (sz - ez) * (sz - ez));

            var tangentSX = (float)Math.Cos(-StartNode.Yaw) * radius;
            var tangentEX = (float)Math.Cos(-EndNode.Yaw) * radius;
            var tangentSZ = (float)Math.Sin(-StartNode.Yaw) * radius;
            var tangentEZ = (float)Math.Sin(-EndNode.Yaw) * radius;

            for (int k = 0; k < steps; k++)
            {
                var s = (float) k/(float) (steps - 1);
                var x = (float) Ets2CurveHelper.Hermite(s, sx, ex, tangentSX, tangentEX);
                var z = (float) Ets2CurveHelper.Hermite(s, sz, ez, tangentSZ, tangentEZ);
                var tx = (float) Ets2CurveHelper.HermiteTangent(s, sx, ex, tangentSX, tangentEX);
                var ty = (float) Ets2CurveHelper.HermiteTangent(s, sz, ez, tangentSZ, tangentEZ);
                var yaw = (float) Math.Atan2(ty, tx);
                x += (float) Math.Sin(-yaw)*(leftlane ? -1 : 1)*(RoadLook.Offset + (0.5f + lane)*4.5f);
                z += (float) Math.Cos(-yaw)*(leftlane ? -1 : 1)*(RoadLook.Offset + (0.5f + lane)*4.5f);
                ps[k] = new Ets2Point(x, 0, z, yaw);
            }

            return ps;
        }
示例#12
0
 public bool CloseTo(Ets2Point pt)
 {
     return(DistanceTo(pt) <= 2f);
 }