add rework vh process and add post process

This commit is contained in:
afischerdev 2023-02-19 13:45:47 +01:00
parent c586245db5
commit 15dd1f30f1
2 changed files with 122 additions and 17 deletions

View file

@ -1080,7 +1080,9 @@ public final class OsmTrack {
VoiceHintProcessor vproc = new VoiceHintProcessor(rc.turnInstructionCatchingRange, rc.turnInstructionRoundabouts); VoiceHintProcessor vproc = new VoiceHintProcessor(rc.turnInstructionCatchingRange, rc.turnInstructionRoundabouts);
List<VoiceHint> results = vproc.process(inputs); List<VoiceHint> results = vproc.process(inputs);
for (VoiceHint hint : results) { double minDistance = getMinDistance();
List < VoiceHint > resultsLast = vproc.postProcess(results, rc.turnInstructionCatchingRange, minDistance);
for (VoiceHint hint: resultsLast) {
voiceHints.list.add(hint); voiceHints.list.add(hint);
} }

View file

@ -9,18 +9,22 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
public final class VoiceHintProcessor { public final class VoiceHintProcessor {
private double catchingRange; // range to catch angles and merge turns
double SIGNIFICANT_ANGLE = 22.5;
double INTERNAL_CATCHING_RANGE = 2.;
// private double catchingRange; // range to catch angles and merge turns
private boolean explicitRoundabouts; private boolean explicitRoundabouts;
public VoiceHintProcessor(double catchingRange, boolean explicitRoundabouts) { public VoiceHintProcessor(double catchingRange, boolean explicitRoundabouts) {
this.catchingRange = catchingRange; // this.catchingRange = catchingRange;
this.explicitRoundabouts = explicitRoundabouts; this.explicitRoundabouts = explicitRoundabouts;
} }
private float sumNonConsumedWithinCatchingRange(List<VoiceHint> inputs, int offset) { private float sumNonConsumedWithinCatchingRange(List<VoiceHint> inputs, int offset) {
double distance = 0.; double distance = 0.;
float angle = 0.f; float angle = 0.f;
while (offset >= 0 && distance < catchingRange) { while (offset >= 0 && distance < INTERNAL_CATCHING_RANGE) {
VoiceHint input = inputs.get(offset--); VoiceHint input = inputs.get(offset--);
if (input.turnAngleConsumed) { if (input.turnAngleConsumed) {
break; break;
@ -60,6 +64,10 @@ public final class VoiceHintProcessor {
for (int hintIdx = 0; hintIdx < inputs.size(); hintIdx++) { for (int hintIdx = 0; hintIdx < inputs.size(); hintIdx++) {
VoiceHint input = inputs.get(hintIdx); VoiceHint input = inputs.get(hintIdx);
if (input.cmd == VoiceHint.BL) {
results.add(input);
continue;
}
float turnAngle = input.goodWay.turnangle; float turnAngle = input.goodWay.turnangle;
distance += input.goodWay.linkdist; distance += input.goodWay.linkdist;
int currentPrio = input.goodWay.getPrio(); int currentPrio = input.goodWay.getPrio();
@ -67,6 +75,7 @@ public final class VoiceHintProcessor {
int minPrio = Math.min(oldPrio, currentPrio); int minPrio = Math.min(oldPrio, currentPrio);
boolean isLink2Highway = input.oldWay.isLinktType() && !input.goodWay.isLinktType(); boolean isLink2Highway = input.oldWay.isLinktType() && !input.goodWay.isLinktType();
boolean isHighway2Link = !input.oldWay.isLinktType() && input.goodWay.isLinktType();
if (input.oldWay.isRoundabout()) { if (input.oldWay.isRoundabout()) {
roundAboutTurnAngle += sumNonConsumedWithinCatchingRange(inputs, hintIdx); roundAboutTurnAngle += sumNonConsumedWithinCatchingRange(inputs, hintIdx);
@ -101,14 +110,18 @@ public final class VoiceHintProcessor {
float minAngle = 180.f; float minAngle = 180.f;
float minAbsAngeRaw = 180.f; float minAbsAngeRaw = 180.f;
boolean isBadwayLink = false;
if (input.badWays != null) { if (input.badWays != null) {
for (MessageData badWay : input.badWays) { for (MessageData badWay : input.badWays) {
int badPrio = badWay.getPrio(); int badPrio = badWay.getPrio();
float badTurn = badWay.turnangle; float badTurn = badWay.turnangle;
if (badWay.isLinktType()) {
isBadwayLink = true;
}
boolean isBadHighway2Link = !input.oldWay.isLinktType() && badWay.isLinktType();
boolean isHighway2Link = !input.oldWay.isLinktType() && badWay.isLinktType(); if (badPrio > maxPrioAll && !isBadHighway2Link) {
if (badPrio > maxPrioAll && !isHighway2Link) {
maxPrioAll = badPrio; maxPrioAll = badPrio;
} }
@ -140,12 +153,17 @@ public final class VoiceHintProcessor {
} }
} }
boolean hasSomethingMoreStraight = Math.abs(turnAngle) - minAbsAngeRaw > 20.; boolean hasSomethingMoreStraight = (Math.abs(turnAngle) - minAbsAngeRaw) > 20.;
// unconditional triggers are all junctions with // unconditional triggers are all junctions with
// - higher detour prios than the minimum route prio (except link->highway junctions) // - higher detour prios than the minimum route prio (except link->highway junctions)
// - or candidate detours with higher prio then the route exit leg // - or candidate detours with higher prio then the route exit leg
boolean unconditionalTrigger = hasSomethingMoreStraight || (maxPrioAll > minPrio && !isLink2Highway) || (maxPrioCandidates > currentPrio); boolean unconditionalTrigger = hasSomethingMoreStraight ||
(maxPrioAll > minPrio && !isLink2Highway) ||
(maxPrioCandidates > currentPrio) ||
VoiceHint.is180DegAngle(turnAngle) ||
(!isHighway2Link && isBadwayLink && Math.abs(turnAngle) > 5.f) ||
(isHighway2Link && !isBadwayLink && Math.abs(turnAngle) < 5.f);
// conditional triggers (=real turning angle required) are junctions // conditional triggers (=real turning angle required) are junctions
// with candidate detours equal in priority than the route exit leg // with candidate detours equal in priority than the route exit leg
@ -158,11 +176,13 @@ public final class VoiceHintProcessor {
input.needsRealTurn = (!unconditionalTrigger) && isStraight; input.needsRealTurn = (!unconditionalTrigger) && isStraight;
// check for KR/KL // check for KR/KL
if (maxAngle < turnAngle && maxAngle > turnAngle - 45.f - (turnAngle > 0.f ? turnAngle : 0.f)) { if (Math.abs(turnAngle) > 5.) { // don't use to small angles
input.cmd = VoiceHint.KR; if (maxAngle < turnAngle && maxAngle > turnAngle - 45.f - (Math.max(turnAngle, 0.f))) {
} input.cmd = VoiceHint.KR;
if (minAngle > turnAngle && minAngle < turnAngle + 45.f - (turnAngle < 0.f ? turnAngle : 0.f)) { }
input.cmd = VoiceHint.KL; if (minAngle > turnAngle && minAngle < turnAngle + 45.f - (Math.min(turnAngle, 0.f))) {
input.cmd = VoiceHint.KL;
}
} }
input.angle = sumNonConsumedWithinCatchingRange(inputs, hintIdx); input.angle = sumNonConsumedWithinCatchingRange(inputs, hintIdx);
@ -170,7 +190,7 @@ public final class VoiceHintProcessor {
distance = 0.; distance = 0.;
results.add(input); results.add(input);
} }
if (results.size() > 0 && distance < catchingRange) { if (results.size() > 0 && distance < INTERNAL_CATCHING_RANGE) { //catchingRange
results.get(results.size() - 1).angle += sumNonConsumedWithinCatchingRange(inputs, hintIdx); results.get(results.size() - 1).angle += sumNonConsumedWithinCatchingRange(inputs, hintIdx);
} }
} }
@ -185,10 +205,10 @@ public final class VoiceHintProcessor {
if (hint.cmd == 0) { if (hint.cmd == 0) {
hint.calcCommand(); hint.calcCommand();
} }
if (!(hint.needsRealTurn && hint.cmd == VoiceHint.C)) { if (!(hint.needsRealTurn && (hint.cmd == VoiceHint.C || hint.cmd == VoiceHint.BL))) {
double dist = hint.distanceToNext; double dist = hint.distanceToNext;
// sum up other hints within the catching range (e.g. 40m) // sum up other hints within the catching range (e.g. 40m)
while (dist < catchingRange && i > 0) { while (dist < INTERNAL_CATCHING_RANGE && i > 0) {
VoiceHint h2 = results.get(i - 1); VoiceHint h2 = results.get(i - 1);
dist = h2.distanceToNext; dist = h2.distanceToNext;
hint.distanceToNext += dist; hint.distanceToNext += dist;
@ -207,9 +227,92 @@ public final class VoiceHintProcessor {
} }
hint.calcCommand(); hint.calcCommand();
results2.add(hint); results2.add(hint);
} else if (hint.cmd == VoiceHint.BL) {
results2.add(hint);
} else {
if (results2.size() > 0)
results2.get(results2.size() - 1).distanceToNext += hint.distanceToNext;
} }
} }
return results2; return results2;
} }
public List<VoiceHint> postProcess(List<VoiceHint> inputs, double catchingRange, double minRange) {
List<VoiceHint> results = new ArrayList<VoiceHint>();
double distance = 0;
VoiceHint inputLast = null;
ArrayList<VoiceHint> tmpList = new ArrayList<>();
for (int hintIdx = 0; hintIdx < inputs.size(); hintIdx++) {
VoiceHint input = inputs.get(hintIdx);
if (input.cmd == VoiceHint.C && !input.goodWay.isLinktType()) {
int badWayPrio = 0;
for (MessageData md : input.badWays) {
badWayPrio = Math.max(badWayPrio, md.getPrio());
}
if (input.goodWay.getPrio() < badWayPrio) {
results.add(input);
} else {
if (inputLast != null) { // when drop add distance to last
inputLast.distanceToNext += input.distanceToNext;
}
continue;
}
} else {
if (input.distanceToNext < catchingRange) {
double dist = input.distanceToNext;
float angles = input.angle;
int i = 1;
boolean save = true;
tmpList.clear();
while (dist < catchingRange && hintIdx + i < inputs.size()) {
VoiceHint h2 = inputs.get(hintIdx + i);
dist += h2.distanceToNext;
angles += h2.angle;
if (VoiceHint.is180DegAngle(input.angle) || VoiceHint.is180DegAngle(h2.angle)) { // u-turn, 180 degree
save = true;
break;
} else if (Math.abs(angles) > 180 - SIGNIFICANT_ANGLE) { // u-turn, collects e.g. two left turns in range
input.angle = angles;
input.calcCommand();
input.distanceToNext += h2.distanceToNext;
save = true;
hintIdx++;
break;
} else if (Math.abs(angles) < SIGNIFICANT_ANGLE && input.distanceToNext < minRange) {
input.angle = angles;
input.calcCommand();
input.distanceToNext += h2.distanceToNext;
save = true;
hintIdx++;
break;
} else if (Math.abs(input.angle) > SIGNIFICANT_ANGLE) {
tmpList.add(h2);
hintIdx++;
} else if (dist > catchingRange) { // distance reached
break;
} else {
if (inputLast != null) { // when drop add distance to last
inputLast.distanceToNext += input.distanceToNext;
}
save = false;
}
i++;
}
if (save) {
results.add(input); // add when last
if (tmpList.size() > 0) { // add when something in stock
results.addAll(tmpList);
hintIdx += tmpList.size() - 1;
}
}
} else {
results.add(input);
}
inputLast = input;
}
}
return results;
}
} }