public RRTNode GetNodeToGoal()
        {
            if (waypoints.Length == 0.0)
                return null;
            lock (locker)
            {
                RobotTwoWheelState currentState = stateProvider.GetCurrentState(lastCommand);
                IPath path = new PointPath();
                RRTNode startingNode = new RRTNode(currentState);
                RRTNode goalNode;
                //foreach (IPathSegment segment in waypoints)
                //{
                bool foundPath = false;

                Console.WriteLine("Finding a path");
                do
                {
                    startingNode = new RRTNode(currentState);
                    foundPath = rrt.FindPath(ref startingNode, waypoints[1].End, obstacles, out goalNode);
                }
                while (!foundPath && receivedNewPath);
                receivedNewPath = false;
                return goalNode;
            }
        }
Exemple #2
0
        public PointPath ToPointPath()
        {
            PointPath p = new PointPath();

            foreach (LineSegment seg in GetSegmentEnumerator())
            {
                p.Add(new LinePathSegment(seg.P0, seg.P1));
            }

            return(p);
        }
        /// <summary>
        /// walks along the bezier path and creates a straight line segment approximation
        /// </summary>
        /// <param name="path"></param>
        /// <param name="sampleDistance"></param>
        /// <returns></returns>
        public PointPath ConvertBezierPathToPointPath(IPath path, double sampleDistance)
        {
            PointPath pathOut = new PointPath();

            foreach (IPathSegment seg in path)
            {
                if (seg is BezierPathSegment == false) throw new InvalidOperationException();
                BezierPathSegment bseg = seg as BezierPathSegment;

                PointOnPath p = seg.StartPoint;

                double refDist = 0;
                while (refDist == 0)
                {
                    PointOnPath p2;
                    refDist = sampleDistance;
                    p2 = seg.AdvancePoint(p, ref refDist);
                    pathOut.Add(new LinePathSegment(p.pt, p2.pt));
                    p = p2;
                }
            }
            return pathOut;
        }
 public IPath GetPathToGoal()
 {
     if (waypoints.Length == 0.0)
         return null;
     lock (locker)
     {
         RobotTwoWheelState currentState = stateProvider.GetCurrentState(lastCommand);
         IPath path = new PointPath();
         RRTNode startingNode = new RRTNode(currentState);
         RRTNode goalNode;
         //foreach (IPathSegment segment in waypoints)
         //{
         while (rrt.FindPath(ref startingNode, waypoints[1].End, obstacles, out goalNode) == false)
         {
             continue;
         }
         //startingNode = goalNode;
         IPath segmentToGoal = GetFinalPath(goalNode);
         // add each small segment of each segment to the path to return
         //foreach (IPathSegment seg in segmentToGoal)
         //path.Add(seg);
         //}
         return segmentToGoal;
     }
 }
 /// <summary>
 /// Find the path from the goal to the starting point
 /// </summary>
 /// <param name="goal"></param>
 /// <returns>path from the start point to the goal point</returns>
 private IPath GetFinalPath(RRTNode goal)
 {
     IPath pathToGoal = new PointPath();
     GetToRoot(goal, ref pathToGoal);
     return pathToGoal;
 }
Exemple #6
0
 /// <summary>
 ///  Output the last planned path
 /// </summary>
 public IPath GetPathToGoal()
 {
     lock (pathLock)
     {
         PointPath newPath = new PointPath();
         if (outputNodeList.Count == 1)
         {
             //If there is only one ode in the planned path, return an IPath with a degenerate segment
             newPath.Add(new LinePathSegment(outputNodeList[0].Value, outputNodeList[0].Value));
         }
         else if (outputNodeList.Count > 1)
         {
             //Build an IPath based on the values of each node in the last planned path
             int segmentCount = outputNodeList.Count - 1;
             for (int i = 0; i < segmentCount; i++)
             {
                 newPath.Add(new LinePathSegment(outputNodeList[i].Value, outputNodeList[i + 1].Value));
             }
         }
         return newPath;
     }
 }
 public void UpdatePath(RRTNode goalNode)
 {
     //create IPath from rootNode
     IPath newNodePath = new PointPath();
     inputList = new List<RobotTwoWheelCommand>();
     ConvertNodeToPath(newNodePath, goalNode, inputList);
     lock (followerLock)
     {
         UpdatePath(newNodePath);
     }
 }
        public IPath GetPathToGoal(IPath[] otherPaths, out IPath sparsePath, out bool inObstacle, out bool wpInObstacle)
        {
            inObstacle = false;
            wpInObstacle = false;
            sparsePath = null;

            if (waypoints == null) return null;
            if (waypointsAchieved >= waypoints.Count) return null;
            if (og == null) return null;
            if (bloatedObstacles == null)
            {
                Console.WriteLine("Convolved obstacles fail!");
                return null;
            }

            // Add current pose position to filteredWaypoints. (FilteredWaypoints is what we will be
            // planning over. Waypoints is list of user given waypoints.)
            List<Waypoint> filteredWaypoints = new List<Waypoint>();
            filteredWaypoints.Add(new Waypoint(pose.ToVector2(), true, 0));

            lock (ogLock)
            {
                if (og.GetCell(pose.x, pose.y) == 255)
                {
                    inObstacle = true;
                    og.SetCell(pose.x, pose.y, 0);
                }
            }

            // Only add user waypoints to PathPoints if they have not been achieved yet.
            // If they are inside an obstacle, return a null path.
            foreach (Waypoint wp in waypoints)
            {
                if (!wp.Achieved)
                {
                    lock (bloatedObstacleLock)
                    {
                        foreach (Polygon p in bloatedObstacles)
                        {
                            if (p.IsInside(wp.Coordinate))
                            {
                                wpInObstacle = true;
                                return null;
                            }
                        }
                    }
                    filteredWaypoints.Add(wp);
                }
            }

            // Plan each segment of the filteredWaypoints individually and stitch them together.
            List<Waypoint> completeRawPath = new List<Waypoint>();

            for (int i = 0; i < filteredWaypoints.Count - 1; i++)
            {
                bool pathOk;
                List<Waypoint> rawPath;

                lock (ogLock)
                {
                    rawPath = dstar.FindPath(filteredWaypoints[i], filteredWaypoints[i + 1], og, out pathOk);
                }

                if (!pathOk) return null;
                else
                {
                    int j;

                    // We want to only add the first path waypoint if it is the first
                    // segment of the whole path.
                    if (i == 0) j = 0;
                    else j = 1;

                    for (; j < rawPath.Count; j++)
                        completeRawPath.Add(rawPath.ElementAt(j));
                }
            }

            if (completeRawPath.Count > 0)
            {
                IPath bezierPath;
                PointPath segmentedBezierPath;

                lock (bloatedObstacleLock)
                {
                    bezierPath = smoother.Wp2BezierPath(completeRawPath, bloatedObstacles, collapseThreshold);
                }

                sparsePath = new PointPath(completeRawPath);
                segmentedBezierPath = smoother.ConvertBezierPathToPointPath(bezierPath, bezierSegmentation);

                // We want to check our sparse path against other sparse paths to see
                // if there are any intersections. If there are, we want to know if the
                // intersections will be a problem. If it is a problem, bloat that sparse path,
                // add it to obstacles, and replan.
                for (int i = 0; i < otherPaths.Length; i++)
                {
                    if (otherPaths[i] != null && otherPaths[i].Count > 0 && i + 1 != robotID)
                    {
                        double intersectDist = DoPathsCollide(sparsePath, otherPaths[i]);

                        if (intersectDist != -1)
                        {
                            PointOnPath collisionPt;
                            int collisionSegmentIndex;

                            double tempDist = intersectDist - collideBackoff;
                            tempDist = Math.Max(0, tempDist);

                            collisionPt = segmentedBezierPath.AdvancePoint(segmentedBezierPath.StartPoint, ref tempDist);
                            collisionSegmentIndex = segmentedBezierPath.IndexOf(collisionPt.segment);

                            segmentedBezierPath.RemoveRange(collisionSegmentIndex, segmentedBezierPath.Count - collisionSegmentIndex);

                            tempDist = intersectDist - collideBackoff;
                            tempDist = Math.Max(0, tempDist);

                            collisionPt = sparsePath.AdvancePoint(sparsePath.StartPoint, ref tempDist);
                            collisionSegmentIndex = sparsePath.IndexOf(collisionPt.segment);

                            sparsePath.RemoveRange(collisionSegmentIndex, sparsePath.Count - collisionSegmentIndex - 1);
                            sparsePath[collisionSegmentIndex].End = collisionPt.pt;
                        }
                    }
                }

                return segmentedBezierPath;
            }

            return null;
        }
        public IPath Wp2BezierPath(List<Waypoint> path, List<Polygon> obstacles, double collapseThreshold)
        {
            List<IPathSegment> segments = new List<IPathSegment>();
            List<Vector2> newPath = new List<Vector2>();
            PointPath bezPath;
            Vector2 P0, P1, P2, P3, dXY, newPoint;
            dXY = new Vector2(0, 0);

            double previousCellValue = path.ElementAt(0).TerrainCost;
            bool inPlateau = false, inLocalMin = false;
            double localMin = Double.MaxValue, localMax = Double.MinValue;

            // Go through the path and mark local minimas and maximas
            for (int i = 1; i < path.Count; i++)
            {
                if (inPlateau)
                {
                    if (previousCellValue != path.ElementAt(i).TerrainCost)
                    {
                        inPlateau = false;
                        //path.ElementAt(i - 1).Critical = true;
                    }
                }
                else
                {
                    if (previousCellValue == path.ElementAt(i).TerrainCost)
                    {
                        inPlateau = true;
                        //path.ElementAt(i - 1).Critical = true;
                    }

                    if (inLocalMin)
                    {
                        if (path.ElementAt(i).TerrainCost < localMin)
                            localMin = path.ElementAt(i).TerrainCost;
                        else
                        {
                            localMin = Double.MaxValue;
                            inLocalMin = false;
                            //path.ElementAt(i - 1).Critical = true;
                        }
                    }
                    else
                    {
                        if (path.ElementAt(i).TerrainCost > localMax)
                            localMax = path.ElementAt(i).TerrainCost;
                        else
                        {
                            localMax = Double.MinValue;
                            inLocalMin = true;
                            path.ElementAt(i - 1).Critical = true;
                        }
                    }
                }

                previousCellValue = path.ElementAt(i).TerrainCost;

            }

            // Collapse nodes down based on proximity to one another
            for (int i = 0; i < path.Count - 1; i++)
            {
                if (path.ElementAt(i).Coordinate.DistanceTo(path.ElementAt(i + 1).Coordinate) < collapseThreshold)
                {
                    if (!path.ElementAt(i).UserWaypoint && !path.ElementAt(i).Critical)
                    {
                        if (!path.ElementAt(i + 1).UserWaypoint && !path.ElementAt(i + 1).Critical)
                        {
                            newPoint = (path.ElementAt(i).Coordinate + path.ElementAt(i + 1).Coordinate) / 2;
                            if (IsClear(newPoint, path.ElementAt(i - 1).Coordinate, obstacles)
                                && IsClear(newPoint, path.ElementAt(i + 2).Coordinate, obstacles))
                            {
                                path.RemoveRange(i, 2);
                                path.Insert(i, new Waypoint(newPoint, false, 0));
                                i--;
                            }
                        }
                        else
                        {
                            newPoint = path.ElementAt(i + 1).Coordinate;
                            if (IsClear(newPoint, path.ElementAt(i - 1).Coordinate, obstacles))
                            {
                                path.RemoveAt(i);
                                i--;
                            }
                        }
                    }
                    else
                    {
                        if (!path.ElementAt(i + 1).UserWaypoint && !path.ElementAt(i + 1).Critical)
                        {
                            newPoint = path.ElementAt(i).Coordinate;
                            if (IsClear(newPoint, path.ElementAt(i + 2).Coordinate, obstacles))
                            {
                                path.RemoveAt(i + 1);
                                i--;
                            }
                        }
                    }
                }
            }

            // Change waypoints to Bezier curves
            for (int i = path.Count - 1; i > 0; i--)
            {
                P3 = path.ElementAt(i).Coordinate;
                P0 = path.ElementAt(i - 1).Coordinate;

                if (i == path.Count - 1)
                    P2 = P3 - ((P3 - P0) / 3);
                else
                {
                    if (dXY.Length > ((P3 - P0) / 4).Length)
                        dXY *= ((P3 - P0) / 4).Length / dXY.Length;
                    P2 = P3 - dXY;
                }

                if (i == 1)
                    P1 = P0 + ((P3 - P0) / 3);
                else
                {
                    dXY = (P3 - path.ElementAt(i - 2).Coordinate) / 6;
                    if (dXY.Length > ((P3 - P0) / 4).Length)
                        dXY *= ((P3 - P0) / 4).Length / dXY.Length;
                    P1 = P0 + dXY;
                }

                segments.Add(new BezierPathSegment(P0, P1, P2, P3, 0.05, false));
            }

            segments.Reverse();
            bezPath = new PointPath(segments);

            return bezPath;
        }
        public IPath Wp2CubicPath(IPath path, List<Polygon> obstacles, double nothing)
        {
            PointPath ret = new PointPath();

            CubicBezier[] bez = SmoothingSpline.BuildCardinalSpline(PathUtils.IPathToPoints(path).ToArray(), null, null, 1.0);
            foreach (CubicBezier b in bez)
            {
                ret.Add(new BezierPathSegment(b, null, false));
            }
            return ret;
        }