Skip to content

Commit

Permalink
Initial StreetPreview random wanderer
Browse files Browse the repository at this point in the history
Currently it's not configurable, just turn it on at build time by making
streetPreviewGo call the streetPreviewGoWander code instead of just
streetPreviewGoInternal. It prefers to continue in the same direction as
the road it comes into an intersection on, but doesn't have any memory
so can switch direction randomly.
  • Loading branch information
davecraig committed Dec 31, 2024
1 parent 61da318 commit f928805
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.Job
import kotlinx.coroutines.async
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch
Expand Down Expand Up @@ -81,6 +82,8 @@ import org.scottishtecharmy.soundscape.utils.getCurrentLocale
import retrofit2.awaitResponse
import java.util.Locale
import kotlin.coroutines.cancellation.CancellationException
import kotlin.math.abs
import kotlin.time.Duration.Companion.milliseconds
import kotlin.time.TimeSource

data class PositionedString(
Expand Down Expand Up @@ -1452,6 +1455,68 @@ class GeoEngine {
}

fun streetPreviewGo() {
if(true) {
streetPreviewGoInternal()
} else {
// Random walker for StreetPreview
CoroutineScope(Job()).launch() {
repeat(1000) {
streetPreviewGoWander()
delay(200.milliseconds)
}
}
}
}

private fun streetPreviewGoWander() {

val start = System.currentTimeMillis()
// Get our current location and figure out what GO means
val location = LngLatAlt(
locationProvider.getCurrentLongitude() ?: 0.0,
locationProvider.getCurrentLatitude() ?: 0.0
)
// Run the code within the treeContext to protect it from changes to the trees whilst it's
// running.
val engine = this
CoroutineScope(Job()).launch(treeContext) {
val choices = streetPreview.getDirectionChoices(engine, location)
var heading = 0.0
if(choices.isNotEmpty()) {
// We want to choose a direction roughly in the forward direction if possible. We
// need to know which road we're coming in on.
val lastHeading = streetPreview.getLastHeading()
// Default to a random road
heading = choices.random().heading
if(!lastHeading.isNaN()) {
// If we came in on a road, then try and keep going in that direction
val trimmedChoices = mutableListOf<StreetPreview.StreetPreviewChoice>()
for (choice in choices) {
if ((choice.heading != lastHeading) && (!choice.heading.isNaN())) {
// Don't add the road we just came in on, or any with a NaN heading.
trimmedChoices.add(choice)
// We want to skew results in favour of continuing onwards so add multiple
// times if the choice is in a direction that's fairly opposite to the road
// we're currently on.
if(abs(choice.heading - lastHeading) > 140.0) {
trimmedChoices.add(choice)
trimmedChoices.add(choice)
trimmedChoices.add(choice)
}
}
}
if(trimmedChoices.isNotEmpty()) {
heading = trimmedChoices.random().heading
}
}
}
streetPreview.go(location, heading.toFloat(), engine)
}
val end = System.currentTimeMillis()
Log.d(TAG, "streetPreviewGo: ${end-start}ms")
}

private fun streetPreviewGoInternal() {

val start = System.currentTimeMillis()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ class StreetPreview {
private var previewState = PreviewState.INITIAL
private var previewRoad: StreetPreviewChoice? = null

private var lastHeading = Double.NaN

fun start() {
previewState = PreviewState.INITIAL
}
Expand Down Expand Up @@ -87,6 +89,7 @@ class StreetPreview {
previewRoad = extendChoice(engine, location, choices[bestIndex])
previewRoad?.let { road ->
engine.locationProvider.updateLocation(road.route.last(), 1.0F)
lastHeading = bearingOfLineFromEnd(road.route.last(), road.route)
}
previewState = PreviewState.AT_NODE
}
Expand Down Expand Up @@ -207,7 +210,7 @@ class StreetPreview {
* Each entry contains a heading, the street name and a list of points that make up the road.
* The app can choose the road based on the heading and then move the user along it.
*/
private fun getDirectionChoices(engine: GeoEngine, location: LngLatAlt): List<StreetPreviewChoice> {
fun getDirectionChoices(engine: GeoEngine, location: LngLatAlt): List<StreetPreviewChoice> {
val choices = mutableListOf<StreetPreviewChoice>()

val start = System.currentTimeMillis()
Expand Down Expand Up @@ -349,6 +352,10 @@ class StreetPreview {
return choices
}

fun getLastHeading() : Double {
return lastHeading
}

companion object {
private const val TAG = "StreetPreview"
}
Expand Down

0 comments on commit f928805

Please sign in to comment.