Ejemplo n.º 1
0
        public override void Process(object param)
        {
            try {
                Trace.CorrelationManager.StartLogicalOperation("ChangeLanes");

                if (!base.BeginProcess())
                {
                    return;
                }

                // check if we were given a parameter
                if (param != null && param is ChangeLaneBehavior)
                {
                    ChangeLaneBehavior clParam = (ChangeLaneBehavior)param;
                    HandleBehavior(clParam);

                    BehaviorManager.TraceSource.TraceEvent(TraceEventType.Verbose, 0, "got new param -- speed {0}, dist {1}, dist timestamp {2}", clParam.SpeedCommand, clParam.MaxDist, clParam.TimeStamp);
                }

                // project the lane paths up to the current time
                RelativeTransform relTransform    = Services.RelativePose.GetTransform(behaviorTimestamp, curTimestamp);
                LinePath          curStartingPath = startingLanePath.Transform(relTransform);
                LinePath          curEndingPath   = endingLanePath.Transform(relTransform);

                // get the starting and ending lane models
                ILaneModel startingLaneModel, endingLaneModel;
                Services.RoadModelProvider.GetLaneChangeModels(curStartingPath, startingLaneWidth, startingNumLanesLeft, startingNumLanesRight,
                                                               curEndingPath, endingLaneWidth, changeLeft, behaviorTimestamp, out startingLaneModel, out endingLaneModel);

                // calculate the max speed
                // TODO: make this look ahead for slowing down
                settings.maxSpeed = GetMaxSpeed(endingLanePath, endingLanePath.ZeroPoint);

                // get the remaining lane change distance
                double remainingDist = GetRemainingLaneChangeDistance();

                BehaviorManager.TraceSource.TraceEvent(TraceEventType.Verbose, 0, "remaining distance is {0}", remainingDist);

                if (cancelled)
                {
                    return;
                }

                // check if we're done
                if (remainingDist <= 0)
                {
                    // create a new stay in lane behavior
                    int deltaLanes = changeLeft ? -1 : 1;
                    StayInLaneBehavior stayInLane = new StayInLaneBehavior(endingLaneID, speedCommand, null, endingLanePath, endingLaneWidth, startingNumLanesLeft + deltaLanes, startingNumLanesRight - deltaLanes);
                    stayInLane.TimeStamp = behaviorTimestamp.ts;
                    Services.BehaviorManager.Execute(stayInLane, null, false);

                    // send completion report
                    ForwardCompletionReport(new SuccessCompletionReport(typeof(ChangeLaneBehavior)));

                    return;
                }

                // calculate the planning distance
                double planningDist = GetPlanningDistance();
                if (planningDist < remainingDist + TahoeParams.VL)
                {
                    planningDist = remainingDist + TahoeParams.VL;
                }

                BehaviorManager.TraceSource.TraceEvent(TraceEventType.Verbose, 0, "planning dist {0}", planningDist);

                // create a linearization options structure
                LinearizationOptions laneOpts = new LinearizationOptions();
                laneOpts.Timestamp = curTimestamp;

                // get the center line of the target lane starting at the distance we want to enter into it
                laneOpts.StartDistance = remainingDist;
                laneOpts.EndDistance   = planningDist;
                LinePath centerLine = endingLaneModel.LinearizeCenterLine(laneOpts);

                // add the final center line as a weighting
                AddTargetPath(centerLine.Clone(), default_lane_alpha_w);

                // pre-pend (0,0) as our position
                centerLine.Insert(0, new Coordinates(0, 0));

                LinePath leftBound  = null;
                LinePath rightBound = null;
                // figure out if the lane is to the right or left of us
                laneOpts.EndDistance = planningDist;
                double leftEndingStartDist, rightEndingStartDist;
                GetLaneBoundStartDists(curEndingPath, endingLaneWidth, out leftEndingStartDist, out rightEndingStartDist);
                if (changeLeft)
                {
                    // we're the target lane is to the left
                    // get the left bound of the target lane

                    laneOpts.StartDistance = Math.Max(leftEndingStartDist, TahoeParams.FL);
                    leftBound = endingLaneModel.LinearizeLeftBound(laneOpts);
                }
                else
                {
                    // we're changing to the right, get the right bound of the target lane
                    laneOpts.StartDistance = Math.Max(rightEndingStartDist, TahoeParams.FL);
                    rightBound             = endingLaneModel.LinearizeRightBound(laneOpts);
                }

                // get the other bound as the starting lane up to 5m before the remaining dist
                laneOpts.StartDistance = TahoeParams.FL;
                laneOpts.EndDistance   = Math.Max(0, remainingDist - 5);
                if (changeLeft)
                {
                    if (laneOpts.EndDistance > 0)
                    {
                        rightBound = startingLaneModel.LinearizeRightBound(laneOpts);
                    }
                    else
                    {
                        rightBound = new LinePath();
                    }
                }
                else
                {
                    if (laneOpts.EndDistance > 0)
                    {
                        leftBound = startingLaneModel.LinearizeLeftBound(laneOpts);
                    }
                    else
                    {
                        leftBound = new LinePath();
                    }
                }

                // append on the that bound of the target lane starting at the remaining dist
                laneOpts.StartDistance = Math.Max(remainingDist, TahoeParams.FL);
                laneOpts.EndDistance   = planningDist;
                if (changeLeft)
                {
                    rightBound.AddRange(endingLaneModel.LinearizeRightBound(laneOpts));
                }
                else
                {
                    leftBound.AddRange(endingLaneModel.LinearizeLeftBound(laneOpts));
                }

                // set up the planning
                smootherBasePath = centerLine;
                AddLeftBound(leftBound, !changeLeft);
                AddRightBound(rightBound, changeLeft);

                Services.UIService.PushLineList(centerLine, curTimestamp, "subpath", true);
                Services.UIService.PushLineList(leftBound, curTimestamp, "left bound", true);
                Services.UIService.PushLineList(rightBound, curTimestamp, "right bound", true);

                if (cancelled)
                {
                    return;
                }

                // set auxillary options
                settings.endingHeading = centerLine.EndSegment.UnitVector.ArcTan;

                // smooth and track that stuff
                SmoothAndTrack(commandLabel, true);
            }
            finally {
                Trace.CorrelationManager.StopLogicalOperation();
            }
        }
 public LocalLaneModel Clone()
 {
     double[] varianceClone = new double[laneYVariance.Length];
     Array.Copy(laneYVariance, varianceClone, laneYVariance.Length);
     return(new LocalLaneModel(lanePath.Clone(), varianceClone, width, widthVariance, probability));
 }
Ejemplo n.º 3
0
        private void DoInitialPlan()
        {
            InitializePlanningSettings();

            curTimestamp = Services.RelativePose.CurrentTimestamp;

            vs = Services.StateProvider.GetVehicleState();

            LinePath curTargetPath = targetPath.Clone();
            LinePath curLeftBound  = null;

            if (leftBound != null)
            {
                curLeftBound = leftBound.Clone();
            }
            LinePath curRightBound = null;

            if (rightBound != null)
            {
                curRightBound = rightBound.Clone();
            }

            // get the distance between our current location and the start point
            double distToStart = Coordinates.Zero.DistanceTo(curTargetPath[0]);

            // extract off the first 5 m of the target path
            LinePath.PointOnPath endTarget = curTargetPath.AdvancePoint(curTargetPath.StartPoint, 12);
            curTargetPath = curTargetPath.SubPath(curTargetPath.StartPoint, endTarget);

            AddTargetPath(curTargetPath.Clone(), 0.005);

            // adjust the left bound and right bounds starting distance
            if (curLeftBound != null)
            {
                LinePath.PointOnPath leftBoundStart = curLeftBound.AdvancePoint(curLeftBound.StartPoint, 2);
                curLeftBound = curLeftBound.SubPath(leftBoundStart, curLeftBound.EndPoint);
                AddLeftBound(curLeftBound, false);
            }
            if (curRightBound != null)
            {
                LinePath.PointOnPath rightBoundStart = curRightBound.AdvancePoint(curRightBound.StartPoint, 2);
                curRightBound = curRightBound.SubPath(rightBoundStart, curRightBound.EndPoint);
                AddRightBound(curRightBound, false);
            }

            // add the intersection pull path
            LinePath            intersectionPullPath = new LinePath();
            double              pullWeight           = 0;
            AbsoluteTransformer trans = Services.StateProvider.GetAbsoluteTransformer(curTimestamp);

            GetIntersectionPullPath(pseudoStartLane.Transform(trans), curTargetPath, intersectionPolygon, true, true, intersectionPullPath, ref pullWeight);

            if (intersectionPullPath.Count > 0)
            {
                AddTargetPath(intersectionPullPath, pullWeight);
            }

            // set up planning details
            // add our position to the current target path
            curTargetPath.Insert(0, new Coordinates(0, 0));
            smootherBasePath = curTargetPath;
            // add the bounds

            // calculate max speed
            settings.maxSpeed = GetMaxSpeed(null, LinePath.PointOnPath.Invalid);

            // fill in auxiliary settings
            if (curLeftBound != null || curRightBound != null)
            {
                settings.endingHeading = curTargetPath.EndSegment.UnitVector.ArcTan;
            }
            disablePathAngleCheck = true;

            settings.Options.w_diff = 4;

            // do the planning
            PlanningResult planningResult = Smooth(false);

            // if the planning was a success, store the result
            if (!planningResult.dynamicallyInfeasible)
            {
                // transform to absolute coordinates
                AbsoluteTransformer absTransform = Services.StateProvider.GetAbsoluteTransformer(curTimestamp);
                turnBasePath = planningResult.smoothedPath.Transform(absTransform.Invert());
            }
        }
Ejemplo n.º 4
0
        public override void Process(object param)
        {
            if (!base.BeginProcess())
            {
                return;
            }

            // check if we're given a param
            if (param != null && param is TurnBehavior)
            {
                TurnBehavior turnParam = (TurnBehavior)param;

                HandleTurnBehavior(turnParam);

                BehaviorManager.TraceSource.TraceEvent(TraceEventType.Information, 0, "turn behavior - got new param, speed command {0}", turnParam.SpeedCommand);
            }

            LinePath curTargetPath = targetPath.Clone();
            LinePath curLeftBound  = null;

            if (leftBound != null)
            {
                curLeftBound = leftBound.Clone();
            }
            LinePath curRightBound = null;

            if (rightBound != null)
            {
                curRightBound = rightBound.Clone();
            }
            // transform the path into the current timestamp
            if (behaviorTimestamp != curTimestamp)
            {
                // get the relative transform
                RelativeTransform relTransform = Services.RelativePose.GetTransform(behaviorTimestamp, curTimestamp);
                BehaviorManager.TraceSource.TraceEvent(TraceEventType.Verbose, 0, "in turn behavior, transforming from {0}->{1}, wanted {2}->{3}", relTransform.OriginTimestamp, relTransform.EndTimestamp, behaviorTimestamp, curTimestamp);
                curTargetPath.TransformInPlace(relTransform);
                if (curLeftBound != null)
                {
                    curLeftBound.TransformInPlace(relTransform);
                }
                if (curRightBound != null)
                {
                    curRightBound.TransformInPlace(relTransform);
                }
            }

            // get the distance between our current location and the start point
            double distToStart = Coordinates.Zero.DistanceTo(curTargetPath[0]);

            double startDist = Math.Max(0, TahoeParams.FL - distToStart);

            // extract off the first 5 m of the target path
            LinePath.PointOnPath endTarget = curTargetPath.AdvancePoint(curTargetPath.StartPoint, TahoeParams.VL);
            curTargetPath = curTargetPath.SubPath(curTargetPath.StartPoint, endTarget);
            curTargetPath = curTargetPath.RemoveZeroLengthSegments();

            // adjust the left bound and right bounds starting distance
            if (curLeftBound != null)
            {
                LinePath.PointOnPath leftBoundStart = curLeftBound.AdvancePoint(curLeftBound.StartPoint, 2);
                curLeftBound = curLeftBound.SubPath(leftBoundStart, curLeftBound.EndPoint);
                AddLeftBound(curLeftBound, false);
                Services.UIService.PushLineList(curLeftBound, curTimestamp, "left bound", true);
            }

            if (curRightBound != null)
            {
                LinePath.PointOnPath rightBoundStart = curRightBound.AdvancePoint(curRightBound.StartPoint, 2);
                curRightBound = curRightBound.SubPath(rightBoundStart, curRightBound.EndPoint);
                AddRightBound(curRightBound, false);

                Services.UIService.PushLineList(curRightBound, curTimestamp, "right bound", true);
            }

            if (cancelled)
            {
                return;
            }

            BehaviorManager.TraceSource.TraceEvent(TraceEventType.Verbose, 0, "in turn behavior, dist to start: {0}", distToStart);
            if (distToStart < TahoeParams.FL * 0.75)
            {
                BehaviorManager.TraceSource.TraceEvent(TraceEventType.Information, 0, "in turn behavior, past start point of target path");
                // return a completion report
                ForwardCompletionReport(new SuccessCompletionReport(typeof(TurnBehavior)));
            }

            AddTargetPath(curTargetPath.Clone(), 0.005);

            // transform the pseudo start lane to the current timestamp
            AbsoluteTransformer trans        = Services.StateProvider.GetAbsoluteTransformer(curTimestamp);
            LinePath            curStartPath = pseudoStartLane.Transform(trans);

            // add the intersection pull path
            LinePath intersectionPullPath = new LinePath();
            double   pullWeight           = 0;

            GetIntersectionPullPath(curStartPath, curTargetPath, intersectionPolygon, true, true, intersectionPullPath, ref pullWeight);

            if (intersectionPullPath.Count > 0)
            {
                AddTargetPath(intersectionPullPath, pullWeight);
            }

            // set up planning details
            // add our position to the current target path
            LinePath origTargetPath = curTargetPath.Clone();

            curTargetPath.Insert(0, new Coordinates(0, 0));
            //curTargetPath.Insert(1, new Coordinates(1, 0));

            smootherBasePath = curTargetPath;
            // add the bounds

            // calculate max speed
            settings.maxSpeed       = GetMaxSpeed(null, LinePath.PointOnPath.Invalid);
            settings.Options.w_diff = 4;

            BehaviorManager.TraceSource.TraceEvent(TraceEventType.Information, 0, "max speed set to {0}", settings.maxSpeed);

            if (cancelled)
            {
                return;
            }

            Services.UIService.PushLineList(curTargetPath, curTimestamp, "subpath", true);

            // set the avoidance path to the previously planned path
            // transform to the current timestamp
            disablePathAngleCheck = true;
            if (turnBasePath != null)
            {
                avoidanceBasePath = turnBasePath.Transform(trans);
                avoidanceBasePath = avoidanceBasePath.SubPath(avoidanceBasePath.GetClosestPoint(Coordinates.Zero), avoidanceBasePath.EndPoint);
                maxAvoidanceBasePathAdvancePoint = avoidanceBasePath.GetPointOnPath(1);

                if (avoidanceBasePath.PathLength > 7.5)
                {
                    smootherBasePath = avoidanceBasePath.SubPath(avoidanceBasePath.StartPoint, avoidanceBasePath.AdvancePoint(avoidanceBasePath.EndPoint, -7.5));
                }
                else
                {
                    smootherBasePath = avoidanceBasePath.Clone();
                }

                disablePathAngleCheck = false;
            }

            // fill in auxiliary settings
            if (curLeftBound != null || curRightBound != null)
            {
                settings.endingHeading = curTargetPath.EndSegment.UnitVector.ArcTan;
            }

            settings.endingPositionFixed = false;
            settings.endingPositionMax   = 16;
            settings.endingPositionMin   = -16;
            if (curLeftBound != null && curLeftBound.Count > 0 && curTargetPath.Count > 0)
            {
                double leftWidth = curLeftBound[0].DistanceTo(origTargetPath[0]) - TahoeParams.T / 2;
                settings.endingPositionMax   = leftWidth;
                settings.endingPositionFixed = true;
            }

            if (curRightBound != null && curRightBound.Count > 0 && curTargetPath.Count > 0)
            {
                double rightWidth = curRightBound[0].DistanceTo(origTargetPath[0]) - TahoeParams.T / 2;
                settings.endingPositionFixed = true;
                settings.endingPositionMin   = -rightWidth;
            }

            //disablePathAngleCheck = true;
            //useAvoidancePath = true;

            // do the planning
            SmoothAndTrack(commandLabel, true);
        }
        private LinePath ReplaceFirstPoint(LinePath path, LinePath.PointOnPath maxAdvancePoint, Coordinates pt)
        {
            LinePath ret;
            if (!disablePathAngleCheck) {
                // start walking down the path until the angle is cool
                double angle_threshold = pathAngleMax;
                LinePath.PointOnPath newPoint = new LinePath.PointOnPath();
                for (double dist = 0; dist < pathAngleCheckMax; dist += 1) {
                    // get the point advanced from the 2nd point on the base path by dist
                    double distTemp = dist;
                    newPoint = path.AdvancePoint(path.GetPointOnPath(1), ref distTemp);

                    // check if we're past the end
                    if (distTemp > 0) {
                        break;
                    }
                    else if (maxAdvancePoint.Valid && newPoint >= maxAdvancePoint) {
                        newPoint = maxAdvancePoint;
                        break;
                    }

                    // check if the angle is coolness or not
                    double angle = Math.Acos((newPoint.Location-pt).Normalize().Dot(path.GetSegment(newPoint.Index).UnitVector));

                    if (angle < angle_threshold) {
                        break;
                    }
                }

                // create a new version of the base path with the stuff section removed
                ret = path.RemoveBetween(path.StartPoint, newPoint);
                ret[0] = pt;
            }
            else {
                ret = path.Clone();
                ret[0] = pt;
            }

            return ret;
        }