@@ -30,6 +30,8 @@ import com.lambda.util.math.minus
3030import com.lambda.util.math.plus
3131import com.lambda.util.math.times
3232import com.lambda.util.world.FastVector
33+ import com.lambda.util.world.add
34+ import com.lambda.util.world.fastVectorOf
3335import com.lambda.util.world.string
3436import com.lambda.util.world.toCenterVec3d
3537import kotlin.math.min
@@ -146,33 +148,33 @@ class DStarLite(
146148
147149 /* *
148150 * Invalidates a node (e.g., it became an obstacle) and updates affected neighbors.
149- * Call `computeShortestPath()` afterwards.
150151 */
151152 fun invalidate (u : FastVector ) {
152- // 1. Invalidate node in graph and get its direct valid neighbors
153- // This also clears the neighbors' cached successors, forcing re-initialization.
154- val neighborsToUpdate = graph.invalidate(u)
155-
156- // 2. Update the rhs value for all affected neighbors.
157- // Since their edge information might change upon re-initialization,
158- // the safest approach is to recompute their rhs from scratch.
159- neighborsToUpdate.forEach { neighbor ->
160- if (neighbor != goal) {
161- // Recompute rhs based on its *potentially new* set of successors
162- // Note: minSuccessorCost will trigger re-initialization
163- setRHS(neighbor, minSuccessorCost(neighbor))
164- }
165- // Check consistency and update queue status for the neighbor
166- updateVertex(neighbor)
153+ graph.neighbors(u).forEach { v ->
154+ graph.invalidated.add(v)
155+ updateEdge(u, v, INF )
156+ updateEdge(v, u, INF )
167157 }
168-
169- // 3. Update the invalidated node itself (likely sets g=INF, rhs=INF)
170- if (u != goal) {
171- setRHS(u, minSuccessorCost(u)) // Should return INF
158+ graph.invalidated.forEach { v ->
159+ val currentConnections = graph.successors(v)
160+ val actualConnections = graph.initialize(v)
161+ val changedConnections = currentConnections.filter { (succ, cost) -> cost != actualConnections[succ] }
162+ val newConnections = actualConnections.filter { (succ, _) -> succ !in currentConnections }
163+ val removedConnections = currentConnections.filter { (succ, _) -> succ !in actualConnections }
164+ changedConnections.forEach { (succ, cost) ->
165+ updateEdge(v, succ, cost)
166+ updateEdge(succ, v, cost)
167+ }
168+ newConnections.forEach { (succ, cost) ->
169+ updateEdge(v, succ, cost)
170+ updateEdge(succ, v, cost)
171+ }
172+ removedConnections.forEach { (succ, _) ->
173+ updateEdge(v, succ, INF )
174+ updateEdge(succ, v, INF )
175+ }
172176 }
173- // Ensure g is INF and update queue status
174- setG(u, INF )
175- updateVertex(u)
177+ graph.invalidated.clear()
176178 }
177179
178180 /* *
@@ -184,13 +186,18 @@ class DStarLite(
184186 */
185187 fun updateEdge (u : FastVector , v : FastVector , c : Double ) {
186188 val cOld = graph.cost(u, v)
189+ if (cOld == c) return
187190 graph.setCost(u, v, c)
188191 if (cOld > c) {
189192 if (u != goal) setRHS(u, min(rhs(u), c + g(v)))
190193 } else if (rhs(u) == cOld + g(v)) {
191194 if (u != goal) setRHS(u, minSuccessorCost(u))
192195 }
193196 updateVertex(u)
197+ // if (c == INF) {
198+ // graph.removeEdge(u, v)
199+ // graph.removeEdge(v, u)
200+ // }
194201 }
195202
196203 /* *
0 commit comments