// @Override public void execute2(SensorData data, ModifiableAction action) { double absMeasure = Math.abs(situation.getMeasure()); double trackPos = data.getTrackPosition(); double trackAngle = data.getAngleToTrackAxis(); boolean mirror = situation.isRight(); if (mirror) { trackPos *= -1.0; trackAngle *= -1.0; } // 0.976807459 0,008231851 -0,209828013 -0,634093073 0,046558592 -0,079286572 1,05025865 // 0,517923684 -0,158864381 1,460560156 0,944967234 0,836506662 0,99226593 1,01798939 double result = 0.002708663 * absMeasure * absMeasure + 0.983090667 * trackPos * trackPos + 0.995064624 * trackAngle * trackAngle + 0.0 * absMeasure * trackPos + 1.695369918 * absMeasure * trackAngle + 1.010313665 * trackPos * trackAngle + 1.020039262; if (mirror) { result *= -1.0; } result = Math.min(45.0, Math.max(-45.0, result)); action.setSteering(result / 45.0); action.limitValues(); }
@Override public void execute(SensorData data, ModifiableAction action) { // steering based on the "biggest sensor value" heuristic double[] rawSensors = data.getRawTrackEdgeSensors(); int index = 0; double longest = rawSensors[0]; for (int i = 1; i < rawSensors.length; ++i) { if (rawSensors[i] > longest) { index = i; longest = rawSensors[i]; } } double angleD = -angles[index]; if (TEXT_DEBUG) { System.out.println( Utils.timeToExactString(data.getCurrentLapTime()) + " @ " + data.getDistanceRacedS() + "- track: " + data.getTrackPositionS() + ", index: " + index + ", angleD: " + Utils.dTS(angleD)); } double absMeasure = Math.abs(situation.getMeasure()); if (absMeasure >= 20.0 && absMeasure < 35.0) { angleD *= 1.0 + ((absMeasure - 20.0) / (35.0 - 20.0)); } else if (absMeasure >= 35.0 && absMeasure < 60.0) { angleD *= 2.0 + ((absMeasure - 35.0) / (60.0 - 35.0)); } else if (absMeasure >= 60.0) { angleD *= 3.0; } if (TEXT_DEBUG) { System.out.println("absMeasure: " + Utils.dTS(absMeasure) + ", angleD: " + Utils.dTS(angleD)); } double trackPos = data.getTrackPosition(); double trackAngle = data.getAngleToTrackAxis(); if (situation.isCorner()) { boolean mirror = situation.isRight(); if (mirror) { trackPos *= -1.0; trackAngle *= -1.0; angleD *= -1.0; index = 18 - index; } double absTrackPos = SensorData.calcAbsoluteTrackPosition(trackPos, trackWidth); // inside if (absTrackPos - (CAR_WIDTH * 0.5) < INSIDE_MARGIN && trackAngle < 0.0) { double beta = (INSIDE_MARGIN - (absTrackPos - (CAR_WIDTH * 0.5))) / INSIDE_MARGIN; if (TEXT_DEBUG) { System.out.println("Inside"); } // not so close -> open steering if (beta < 0.5) { // System.out.println("IN - Opening@"+Utils.dTS(data.getDistanceFromStartLine())); if (TEXT_DEBUG) { System.out.print("Beta: " + Utils.dTS(beta) + ", old: " + Utils.dTS(angleD)); } double alpha = (beta - 0.5) * -(1 / 0.5); angleD *= alpha; if (TEXT_DEBUG) { System.out.println(", alpha: " + Utils.dTS(alpha) + ", new: " + Utils.dTS(angleD)); } } else { // System.out.println("IN - Other@"+Utils.dTS(data.getDistanceFromStartLine())); beta = Math.min(beta, 1.0); // very close, steer in the other direction if (TEXT_DEBUG) { System.out.print("Beta: " + Utils.dTS(beta) + ", old: " + Utils.dTS(angleD)); } double alpha = (beta - 0.5) * (1 / 0.5); angleD = Math.toDegrees(trackAngle) * alpha; // angleD = 2.0*alpha; if (TEXT_DEBUG) { System.out.println(", alpha: " + Utils.dTS(alpha) + ", new: " + Utils.dTS(angleD)); } } } // outside if (absTrackPos + (CAR_WIDTH * 0.5) > trackWidth - OUTSIDE_MARGIN) { // System.out.println("OUT@"+Utils.dTS(data.getDistanceFromStartLine())); if (TEXT_DEBUG) { System.out.println("Outside"); } // increase steering angle double alpha = Math.min(absMeasure, OUTSIDE_DOUBLE) / OUTSIDE_DOUBLE; double beta = ((absTrackPos + (CAR_WIDTH * 0.5)) - (trackWidth - OUTSIDE_MARGIN)) / OUTSIDE_MARGIN; if (TEXT_DEBUG) { System.out.print("Beta: " + Utils.dTS(beta) + ", old: " + Utils.dTS(angleD)); } beta = Math.min(beta, 1.0); angleD *= 1.0 + (alpha * beta); if (TEXT_DEBUG) { System.out.println( ", 1+alpha: " + Utils.dTS(1.0 + alpha) + ", new: " + Utils.dTS(angleD)); } } // if(Math.abs(Math.toDegrees(trackAngle)) < 10.0){ // System.out.println(absMeasure + ";" + trackPos + ";" + Math.toDegrees(trackAngle) + ";" // + index + ";" + angleD); // } if (mirror) { angleD *= -1.0; } } angleD = Math.min(45.0, Math.max(-45.0, angleD)); action.setSteering(angleD / 45.0); action.limitValues(); if (TEXT_DEBUG) { System.out.println("Final value: " + action.getSteeringS()); } }
private PlanElement2011 plan( PlanStackData planData, SensorData data, TrackModel trackModel, OpponentObserver observer, boolean planning) { int index = planData.currentSegment(); TrackSegment current = trackModel.getSegment(index); TrackSegment next = trackModel.getSegment(trackModel.incrementIndex(index)); TrackSegment prev = trackModel.getSegment(trackModel.decrementIndex(index)); double end = planData.end(); double start = planData.start(); if (Plan.TEXT_DEBUG && planning) { plan.println(""); plan.println("------------ PlanStraight------------"); plan.println( "Start/End: " + Utils.dTS(start) + ", " + Utils.dTS(end) + " [" + Utils.dTS(end - start) + "m]" + " - "); planData.print(); plan.println(""); } // plan like the last element? boolean planLikeLast = current.contains(data.getDistanceFromStartLine()); if (planLikeLast) { start = data.getDistanceRaced(); if (Plan.TEXT_DEBUG && planning) { plan.println("This is the last segment to plan for..."); } } // check if we can combine the planning of this segment and the previous if (!planLikeLast && prev.isStraight()) { if (Plan.TEXT_DEBUG && planning) { plan.println("Previous is also straight, checking further..."); } if (start - prev.getLength() <= data.getDistanceRaced()) { if (Plan.TEXT_DEBUG && planning) { plan.println("Prev is the last segment to plan for"); } start = data.getDistanceRaced(); planLikeLast = true; } else { if (Plan.TEXT_DEBUG && planning) { plan.println("Prev is also a middle segment"); } start -= prev.getLength(); int prevIndex = trackModel.decrementIndex(index); int prevPrevIndex = trackModel.decrementIndex(prevIndex); if (Plan.TEXT_DEBUG && planning) { plan.println("Switching prev from " + prevIndex + " to " + prevPrevIndex); } prev = trackModel.getSegment(prevPrevIndex); } if (Plan.TEXT_DEBUG && planning) { plan.println( "Moving start to " + Utils.dTS(start) + ", new length " + Utils.dTS(end - start) + "m"); } planData.popSegment(); } double brakeDistance = 0.0; if (planData.approachSpeed != Plan2013.MAX_SPEED) { if (planData.first()) { brakeDistance = plan.calcBrakingZoneStraight(data.getSpeed(), end - start, planData.approachSpeed); } else { brakeDistance = plan.calcBrakingZoneStraight(planData.speed(), end - start, planData.approachSpeed); } } if (Plan.TEXT_DEBUG && planning) { plan.println("Brake distance: " + Utils.dTS(brakeDistance) + "m"); } Point2D targetPosition = OpponentObserver.NO_RECOMMENDED_POINT; if (observer.otherCars() && observer.getRecommendedPosition() != OpponentObserver.NO_RECOMMENDED_POINT) { Point2D recommendation = new Point2D.Double(); recommendation.setLocation(observer.getRecommendedPosition()); if (start <= recommendation.getY() && recommendation.getY() < end) { targetPosition = new Point2D.Double(); targetPosition.setLocation(recommendation); } } // track positions ArrayList<Interpolator> positions = new ArrayList<>(); double currStart = start; double remainingLength = end - start; double currPosition = plan.getAnchorPoint(prev, current); if (planLikeLast) { currPosition = data.getTrackPosition(); } if (Plan.TEXT_DEBUG && planning) { plan.println(Utils.dTS(remainingLength) + "m remain..."); } if (targetPosition != OpponentObserver.NO_RECOMMENDED_POINT) { if (Plan.TEXT_DEBUG && planning) { plan.println("I need to take care of other cars, point is " + targetPosition.toString()); plan.println("Right now, i'm planning with currStart: " + Utils.dTS(currStart)); } if (targetPosition.getY() < currStart) { if (Plan.TEXT_DEBUG && planning) { plan.println("Point is before currStart, moving it to +1m"); } targetPosition.setLocation(targetPosition.getX(), targetPosition.getY() + 1.0); } if (Plan.TEXT_DEBUG && planning) { plan.println("Checking, if there is enough room..."); } double lengthNeeded = targetPosition.getY() - currStart; if (Plan.TEXT_DEBUG && planning) { plan.println( "I need at least " + Utils.dTS(lengthNeeded) + "m, " + Utils.dTS(remainingLength) + "m remain"); } if (remainingLength < lengthNeeded) { targetPosition = OpponentObserver.NO_RECOMMENDED_POINT; if (Plan.TEXT_DEBUG && planning) { plan.println("Cannot overtake, not enough room"); } } } if (targetPosition != OpponentObserver.NO_RECOMMENDED_POINT) { if (Plan.TEXT_DEBUG && planning) { plan.println("Trying to overtake"); } // switch Position 1 double[] xP = new double[3]; double[] yP = new double[3]; xP[0] = currStart; xP[2] = targetPosition.getY(); xP[1] = (xP[0] + xP[2]) / 2.0; yP[0] = currPosition; yP[2] = targetPosition.getX(); yP[1] = (yP[0] + yP[2]) / 2.0; if (Plan.TEXT_DEBUG && planning) { plan.println("Switch Position 1:"); for (int k = 0; k < xP.length; ++k) { plan.println(xP[k] + " , " + yP[k]); } } CubicSpline spline = new CubicSpline(xP, yP); spline.setDerivLimits(0.0, 0.0); positions.add(new FlanaganCubicWrapper(spline)); currStart = xP[2]; remainingLength = end - currStart; currPosition = targetPosition.getX(); // overtaking if (Plan.TEXT_DEBUG && planning) { plan.println("Overtaking line"); } xP = new double[3]; xP[0] = currStart; xP[2] = end - 150.0; if (Plan.TEXT_DEBUG && planning) { plan.println( "Overtaking line: " + Utils.dTS(currStart) + " " + Utils.dTS(end - 150.0) + " " + targetPosition.getX()); } positions.add(new ConstantValue(xP[0], xP[2], targetPosition.getX())); currStart = xP[2]; remainingLength = end - currStart; currPosition = targetPosition.getX(); } // simply drive towards the target position for the next corner if (Plan.TEXT_DEBUG && planning) { plan.println("Planning towards the next corner..."); } double[] xP = new double[3]; double[] yP = new double[3]; xP[0] = currStart; xP[2] = end; xP[1] = (xP[0] + xP[2]) / 2.0; yP[0] = currPosition; double absCurrPosition = SensorData.calcAbsoluteTrackPosition(currPosition, trackModel.getWidth()); double possibleDelta = Plan2013.calcPossibleSwitchDelta(data, end - currStart); double anchor = plan.getAnchorPoint(current, next); double absDesiredPosition = SensorData.calcAbsoluteTrackPosition(anchor, trackModel.getWidth()); if (Plan.TEXT_DEBUG && planning) { plan.println("absCurrPosition: " + Utils.dTS(absCurrPosition)); plan.println("PossibleDelta: " + Utils.dTS(possibleDelta)); plan.println("absDesiredPosition: " + Utils.dTS(absDesiredPosition)); } if (Math.abs(absDesiredPosition - absCurrPosition) <= possibleDelta) { if (Plan.TEXT_DEBUG && planning) { plan.println("Positioning ok"); } yP[2] = plan.getAnchorPoint(current, next); } else { // move to the right if (anchor < 0) { yP[2] = SensorData.calcRelativeTrackPosition( absCurrPosition + possibleDelta, trackModel.getWidth()); } else { // move to the left yP[2] = SensorData.calcRelativeTrackPosition( absCurrPosition - possibleDelta, trackModel.getWidth()); } } yP[1] = (yP[0] + yP[2]) / 2.0; if (Plan.TEXT_DEBUG && planning) { plan.println("Position towards the next corner:"); for (int k = 0; k < xP.length; ++k) { plan.println(xP[k] + " , " + yP[k]); } } CubicSpline spline = new CubicSpline(xP, yP); spline.setDerivLimits(0.0, 0.0); positions.add(new FlanaganCubicWrapper(spline)); // target speed double[] xS; double[] yS; if (brakeDistance >= end - start || brakeDistance == 0.0) { xS = new double[3]; yS = new double[3]; xS[0] = start; xS[2] = end; xS[1] = (xS[0] + xS[2]) / 2.0; if (brakeDistance == 0.0) { yS[0] = Plan2013.MAX_SPEED; yS[1] = Plan2013.MAX_SPEED; yS[2] = Plan2013.MAX_SPEED; planData.approachSpeed = Plan2013.MAX_SPEED; } else { yS[0] = planData.approachSpeed; yS[1] = planData.approachSpeed; yS[2] = planData.approachSpeed; planData.approachSpeed = plan.calcApproachSpeedStraight(planData.approachSpeed, end - start); } } else { xS = new double[4]; yS = new double[4]; xS[0] = start; xS[1] = end - brakeDistance; xS[2] = end - (brakeDistance * 0.99); xS[3] = end; yS[0] = Plan2013.MAX_SPEED; yS[1] = Plan2013.MAX_SPEED; yS[2] = planData.approachSpeed; yS[3] = planData.approachSpeed; planData.approachSpeed = Plan2013.MAX_SPEED; } if (Plan.TEXT_DEBUG && planning) { plan.println("Speed:"); for (int i = 0; i < xS.length; ++i) { plan.println(xS[i] + " , " + yS[i]); } } LinearInterpolator speed; try { speed = new LinearInterpolator(xS, yS); } catch (RuntimeException e) { System.out.println("*****************EXCEPTION**************"); System.out.println( "Start/End: " + Utils.dTS(start) + ", " + Utils.dTS(end) + " [" + Utils.dTS(end - start) + "m]" + " - "); System.out.println("Segment: " + current.toString()); System.out.println("Start: " + start); System.out.println("End: " + end); System.out.println("BrakeDistance: " + brakeDistance); System.out.println("Data:"); try { java.io.OutputStreamWriter osw = new java.io.OutputStreamWriter(System.out); SensorData.writeHeader(osw); osw.append('\n'); data.write(osw); osw.flush(); } catch (Exception schwupp) { } System.out.println(""); System.out.println("Speed:"); for (int i = 0; i < xS.length; ++i) { System.out.println(xS[i] + " , " + yS[i]); } System.out.println("Complete Model:"); trackModel.print(); throw e; } PlanElement2011 element = new PlanElement2011(xS[0], xS[xS.length - 1], "Accelerate"); for (Interpolator cs : positions) { element.attachPosition(cs); } element.setSpeed(speed); return element; }