MovableAgentResource

open class MovableAgentResource @JvmOverloads constructor(agentModel: AgentModel, val space: ContinuousProjection<AgentLike>, initPosition: Point2D, name: String? = null, capacity: Int = Defaults.capacity, queue: RequestQ? = null, var velocity: Double = Defaults.velocity, var stepSize: Double = Travel.Defaults.stepSize) : AgentResource, VehicleMovementIfc(source)

An AgentResource whose position is tracked in a ContinuousProjection. Composes the agent-resource semantics (seizable, queueable, on-shift / off-shift, statechart, mailbox, optional AgentPerformance stats) with continuous-space position tracking. Spatial queries on the projection (space.within(p, r), space.neighborsOf(...)) automatically see this resource at its current position.

The agent-layer analog of ksl.modeling.spatial.MovableResource, but built on agent-layer primitives. Differences from the spatial-layer version:

  • Position lives in a ContinuousProjection, not a SpatialModel. Spatial queries on the projection see this resource alongside any other agents.

  • Movement uses the agent-layer travelTo primitive (or any other code that updates the projection's positions). No built-in KSLProcess.transportWith(this) integration — for that path, use the spatial-layer MovableResource directly (possibly with the Phase 4.1 bridge for shared coordinates).

  • Velocity isn't a fixed property of the resource. Each travel specifies its own velocity, which is more flexible (allows loaded vs. empty velocities, fast vs. slow modes) at the cost of one extra parameter per call site.

Typical usage:

class Warehouse(parent: ModelElement) : AgentModel(parent, "warehouse") {
val world: Context<AgentLike> = Context("world")
val floor: ContinuousProjection<AgentLike> =
ContinuousProjection(world, 0.0..100.0, 0.0..100.0)

val forklift: MovableAgentResource = MovableAgentResource(
this, floor, initPosition = Point2D(50.0, 50.0), name = "forklift-1",
)

inner class TaskRunner : Agent("runner") {
val script: KSLProcess = process(isDefaultProcess = true) {
val allocation = seize(forklift)
travelTo(forklift, floor, Point2D(80.0, 20.0), velocity = 2.5)
delay(2.0) // load
travelTo(forklift, floor, Point2D(10.0, 90.0), velocity = 2.5)
delay(2.0) // unload
release(allocation)
}
}
}

Lifecycle: a MovableAgentResource is a ResourceWithQ (via AgentResource), so it's a ModelElement and must be constructed before simulate(). It joins its projection's context automatically at construction and is placed at initPosition.

Constraints on type variance: the projection is typed as ContinuousProjection<AgentLike> so the same projection can hold both Agents and MovableAgentResources (and any other AgentLike types). Models that need a more specific projection type can either keep separate projections per type or upcast this resource to AgentLike at the call site.

Parameters

agentModel

the enclosing AgentModel; required as AgentResource needs an AgentModel parent for its mailbox.

space

the projection that tracks this resource's position. Must hold AgentLike (or compatible) members.

initPosition

starting position in the projection.

name

optional name; defaults to MovableAgentResource_<id>. It also implements VehicleMovementIfc, the movement seam a fleet is written against, so tours, dispatching and a manifest can be driven over a continuous projection by exactly the code that drives them over a guide path. See "The seam" below.

capacity

initial resource capacity (default 1).

queue

optional shared request queue.

velocity

how fast beginTravelTo moves it. A property of the vehicle rather than of each call, because the seam's caller is a fleet that knows what a journey is for and not how fast this particular vehicle goes. travelTo still takes its own velocity per call and is unaffected.

stepSize

the interpolation step, in coordinate units. What a journey is discretised into, and therefore how quickly a redirection or a halt is observed: at most stepSize/velocity later.

Constructors

Link copied to clipboard
constructor(agentModel: AgentModel, space: ContinuousProjection<AgentLike>, initPosition: Point2D, name: String? = null, capacity: Int = Defaults.capacity, queue: RequestQ? = null, velocity: Double = Defaults.velocity, stepSize: Double = Travel.Defaults.stepSize)

Types

Link copied to clipboard
object Defaults

Mutable global defaults for MovableAgentResource construction.

Properties

Link copied to clipboard
open override val distanceTravelled: Double

How far the vehicle has travelled this replication. Never decreases.

Link copied to clipboard

Where it starts each replication.

Link copied to clipboard
open override val isHalted: Boolean

True while the vehicle is stopped short of where it was going, with nothing scheduled.

Link copied to clipboard
open override val operatingTime: Double

How long it has spent travelling this replication.

Link copied to clipboard

The plane this vehicle's positions are expressed in. One per projection.

Link copied to clipboard

Current position in space. Throws if the resource has somehow lost its position (should never happen during normal use, since the resource joins the context at construction and only leaves on explicit context.remove).

Link copied to clipboard
open override val positionNow: LocationIfc

Where the vehicle is now, interpolated to this instant by the step that last completed.

Link copied to clipboard
Link copied to clipboard
Link copied to clipboard

Functions

Link copied to clipboard
open override fun beginTravelTo(destination: LocationIfc, purpose: MovePurpose, waiter: ProcessModel.Entity): HoldQueue?

Sends the vehicle to destination and reports where to wait for it.

Link copied to clipboard
fun halt()

Stops the vehicle where it stands and wakes whoever was waiting for it.

Link copied to clipboard
protected open override fun initialize()

Puts the resource back where it was declared, at the start of every replication.

Link copied to clipboard
open override fun isReachable(destination: LocationIfc): Boolean

True for any location on this plane and inside the projection's bounds.

Link copied to clipboard
open override fun pathDistanceTo(destination: LocationIfc): Double

Straight-line distance across the projection, which on a plane is the path the vehicle would take. Wraps where the projection is a torus, because there the short way round is the way it would actually go.

Link copied to clipboard
fun placeAt(point: Point2D)

Instantly place at the given point, bypassing any motion-time semantics. For continuous-time movement use travelTo from inside a process { } body.

Link copied to clipboard
open override fun resumeHalted()

Starts a halted vehicle again from where it stopped. Harmless on one that is not halted.