嗯
This commit is contained in:
parent
07cb1304d2
commit
d8ed237d46
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,4 +1,8 @@
|
|||||||
import core.TrajectorySimulator
|
import core.TrajectorySimulator
|
||||||
|
import core.SimulatorConfig
|
||||||
|
import core.PhysicsConfig
|
||||||
|
import core.NoiseConfig
|
||||||
|
import core.OutputConfig
|
||||||
import resources.data.sampleRoute
|
import resources.data.sampleRoute
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -22,37 +26,38 @@ fun main() {
|
|||||||
// ════════════════════════════════════════════
|
// ════════════════════════════════════════════
|
||||||
// 第2步:创建模拟器
|
// 第2步:创建模拟器
|
||||||
// ════════════════════════════════════════════
|
// ════════════════════════════════════════════
|
||||||
val simulator = TrajectorySimulator(route)
|
val config = SimulatorConfig(
|
||||||
|
physics = PhysicsConfig(
|
||||||
// ════════════════════════════════════════════
|
totalDistance = 2000.0,
|
||||||
// 第3步:配置参数(可选)
|
duration = 600.0,
|
||||||
// ════════════════════════════════════════════
|
maxVelocity = 4.0,
|
||||||
simulator.setPhysicsParams(
|
minVelocity = 1.8,
|
||||||
totalDistance = 2000.0, // 5公里
|
sampleStepSeconds = 1.0,
|
||||||
duration = 600.0, //
|
modelMaxAccelerationMps2 = 1.2,
|
||||||
maxVelocity = 4.0 // 4 m/s (14.4 km/h)
|
seed = 42L
|
||||||
)
|
),
|
||||||
|
noise = NoiseConfig(
|
||||||
simulator.setNoiseParams(
|
gpsErrorStdDev = 0.00002,
|
||||||
gpsErrorStdDev = 0.00002, // GPS误差标准差
|
driftWeight = 0.1
|
||||||
driftWeight = 0.1 // 漂移权重
|
),
|
||||||
|
output = OutputConfig(
|
||||||
|
duration = 600.0,
|
||||||
|
timeStep = 3.0
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
val simulator = TrajectorySimulator(route, config)
|
||||||
|
|
||||||
// ════════════════════════════════════════════
|
// ════════════════════════════════════════════
|
||||||
// 第4步:模拟运动(逐个时间步)
|
// 第4步:模拟运动(逐个时间步)
|
||||||
// ════════════════════════════════════════════
|
// ════════════════════════════════════════════
|
||||||
val timeStep = 3.0
|
val timeStep = config.output.timeStep
|
||||||
val duration = 600.0 // 总模拟时长10分钟
|
val duration = config.output.duration // 总模拟时长10分钟
|
||||||
|
|
||||||
println("时间(秒)\t距离(米)\t速度(m/s)\t加速度(m/s²)\t纬度\t\t经度\t\tGPS误差(m)")
|
println("时间(秒)\t距离(米)\t速度(m/s)\t加速度(m/s²)\t纬度\t\t经度\t\tGPS误差(m)")
|
||||||
println("─".repeat(100))
|
println("─".repeat(100))
|
||||||
|
|
||||||
var time = 0.0
|
val routeStates = simulator.routeOut(duration = duration, timeStep = timeStep)
|
||||||
while (time <= duration) {
|
routeStates.forEach { motionState ->
|
||||||
// 调用模拟器的核心方法,执行完整的4步数据流
|
|
||||||
val motionState = simulator.simulate(time)
|
|
||||||
|
|
||||||
// 输出结果
|
|
||||||
println(
|
println(
|
||||||
"%.1f\t%.1f\t%.3f\t%.3f\t%.6f\t%.6f\t%.6f".format(
|
"%.1f\t%.1f\t%.3f\t%.3f\t%.6f\t%.6f\t%.6f".format(
|
||||||
motionState.time,
|
motionState.time,
|
||||||
@ -64,8 +69,6 @@ fun main() {
|
|||||||
motionState.gpsError
|
motionState.gpsError
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
time += timeStep
|
|
||||||
}
|
}
|
||||||
|
|
||||||
println("\n模拟完成!")
|
println("\n模拟完成!")
|
||||||
|
|||||||
@ -22,19 +22,26 @@ import model.PhysicsState
|
|||||||
class RunnerPhysics(
|
class RunnerPhysics(
|
||||||
private val totalDistance: Double = 0.0, // 总路线距离(米)
|
private val totalDistance: Double = 0.0, // 总路线距离(米)
|
||||||
private val duration: Double = 1000.0, // 总运动时间(秒)
|
private val duration: Double = 1000.0, // 总运动时间(秒)
|
||||||
private val maxVelocity: Double = 4.0 // 最大速度(m/s)
|
private val maxVelocity: Double = 4.0, // 最大速度(m/s)
|
||||||
|
private val minVelocity: Double = (maxVelocity * 0.45).coerceAtLeast(0.5), // 最小速度(m/s)
|
||||||
|
private val sampleStepSeconds: Double = 1.0, // 速度时间线采样间隔(秒)
|
||||||
|
private val modelMaxAccelerationMps2: Double = 1.2, // 模型内最大加速度(m/s²)
|
||||||
|
private val seed: Long? = null // 随机种子(可选)
|
||||||
) {
|
) {
|
||||||
private val derivativeStepSeconds = 1.0
|
private val derivativeStepSeconds = sampleStepSeconds
|
||||||
|
|
||||||
// 接入人类风格距离引擎(仅用于 time -> distance)
|
// 接入人类风格距离引擎(仅用于 time -> distance)
|
||||||
private val distanceEngine: HumanLikeDistanceEngine? =
|
private val distanceEngine: HumanLikeDistanceEngine? =
|
||||||
if (totalDistance > 0.0 && duration > 0.0 && maxVelocity > 0.0) {
|
if (totalDistance > 0.0 && duration > 0.0 && maxVelocity > 0.0 && minVelocity > 0.0) {
|
||||||
HumanLikeDistanceEngine(
|
HumanLikeDistanceEngine(
|
||||||
HumanLikeDistanceConfig(
|
HumanLikeDistanceConfig(
|
||||||
totalDistanceMeters = totalDistance,
|
totalDistanceMeters = totalDistance,
|
||||||
totalDurationSeconds = duration,
|
totalDurationSeconds = duration,
|
||||||
minSpeedMps = (maxVelocity * 0.45).coerceAtLeast(0.5),
|
minSpeedMps = minVelocity.coerceAtMost(maxVelocity - 1e-6),
|
||||||
maxSpeedMps = maxVelocity
|
maxSpeedMps = maxVelocity,
|
||||||
|
sampleStepSeconds = sampleStepSeconds,
|
||||||
|
maxAccelerationMps2 = modelMaxAccelerationMps2,
|
||||||
|
seed = seed
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -5,6 +5,32 @@ import model.MetaCoordinate
|
|||||||
import model.MotionState
|
import model.MotionState
|
||||||
import noise.NoiseProcessor
|
import noise.NoiseProcessor
|
||||||
|
|
||||||
|
data class PhysicsConfig(
|
||||||
|
val totalDistance: Double = 2000.0,
|
||||||
|
val duration: Double = 600.0,
|
||||||
|
val maxVelocity: Double = 4.0,
|
||||||
|
val minVelocity: Double = (maxVelocity * 0.45).coerceAtLeast(0.5),
|
||||||
|
val sampleStepSeconds: Double = 1.0,
|
||||||
|
val modelMaxAccelerationMps2: Double = 1.2,
|
||||||
|
val seed: Long? = null
|
||||||
|
)
|
||||||
|
|
||||||
|
data class NoiseConfig(
|
||||||
|
val gpsErrorStdDev: Double = 0.00002,
|
||||||
|
val driftWeight: Double = 0.3
|
||||||
|
)
|
||||||
|
|
||||||
|
data class OutputConfig(
|
||||||
|
val duration: Double = 600.0,
|
||||||
|
val timeStep: Double = 3.0
|
||||||
|
)
|
||||||
|
|
||||||
|
data class SimulatorConfig(
|
||||||
|
val physics: PhysicsConfig = PhysicsConfig(),
|
||||||
|
val noise: NoiseConfig = NoiseConfig(),
|
||||||
|
val output: OutputConfig = OutputConfig()
|
||||||
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 轨迹模拟器 - 核心协调器,管理整个数据流
|
* 轨迹模拟器 - 核心协调器,管理整个数据流
|
||||||
*
|
*
|
||||||
@ -41,12 +67,35 @@ import noise.NoiseProcessor
|
|||||||
* │ │
|
* │ │
|
||||||
* └─────────────────────────────────────────────────────────┘
|
* └─────────────────────────────────────────────────────────┘
|
||||||
*/
|
*/
|
||||||
class TrajectorySimulator(route: List<MetaCoordinate>) {
|
class TrajectorySimulator(
|
||||||
|
route: List<MetaCoordinate>,
|
||||||
|
initialConfig: SimulatorConfig = SimulatorConfig()
|
||||||
|
) {
|
||||||
|
private var simulatorConfig: SimulatorConfig = initialConfig
|
||||||
|
|
||||||
// 核心引擎(一次性创建,重复使用)
|
// 核心引擎(一次性创建,重复使用)
|
||||||
private val pathInterpolator: PathInterpolator = PathInterpolator(route)
|
private val pathInterpolator: PathInterpolator = PathInterpolator(route)
|
||||||
private val physicsEngine: RunnerPhysics = RunnerPhysics()
|
private var physicsEngine: RunnerPhysics = createPhysicsEngine()
|
||||||
private val noiseProcessor: NoiseProcessor = NoiseProcessor()
|
private var noiseProcessor: NoiseProcessor = createNoiseProcessor()
|
||||||
|
|
||||||
|
private fun createPhysicsEngine(): RunnerPhysics {
|
||||||
|
return RunnerPhysics(
|
||||||
|
totalDistance = simulatorConfig.physics.totalDistance,
|
||||||
|
duration = simulatorConfig.physics.duration,
|
||||||
|
maxVelocity = simulatorConfig.physics.maxVelocity,
|
||||||
|
minVelocity = simulatorConfig.physics.minVelocity,
|
||||||
|
sampleStepSeconds = simulatorConfig.physics.sampleStepSeconds,
|
||||||
|
modelMaxAccelerationMps2 = simulatorConfig.physics.modelMaxAccelerationMps2,
|
||||||
|
seed = simulatorConfig.physics.seed
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createNoiseProcessor(): NoiseProcessor {
|
||||||
|
return NoiseProcessor(
|
||||||
|
gpsErrorStdDev = simulatorConfig.noise.gpsErrorStdDev,
|
||||||
|
driftWeight = simulatorConfig.noise.driftWeight
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 模拟特定时刻的运动状态
|
* 模拟特定时刻的运动状态
|
||||||
@ -98,6 +147,25 @@ class TrajectorySimulator(route: List<MetaCoordinate>) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun routeOut(
|
||||||
|
duration: Double = simulatorConfig.output.duration,
|
||||||
|
timeStep: Double = simulatorConfig.output.timeStep
|
||||||
|
): List<MotionState> {
|
||||||
|
val output = mutableListOf<MotionState>()
|
||||||
|
var time = 0.0
|
||||||
|
while (time <= duration) {
|
||||||
|
output.add(simulate(time))
|
||||||
|
time += timeStep
|
||||||
|
}
|
||||||
|
return output
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setConfig(config: SimulatorConfig) {
|
||||||
|
simulatorConfig = config
|
||||||
|
physicsEngine = createPhysicsEngine()
|
||||||
|
noiseProcessor = createNoiseProcessor()
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置物理引擎参数
|
* 设置物理引擎参数
|
||||||
*
|
*
|
||||||
@ -112,8 +180,32 @@ class TrajectorySimulator(route: List<MetaCoordinate>) {
|
|||||||
duration: Double,
|
duration: Double,
|
||||||
maxVelocity: Double
|
maxVelocity: Double
|
||||||
) {
|
) {
|
||||||
// TODO: 实现参数设置逻辑
|
simulatorConfig = simulatorConfig.copy(
|
||||||
// 可考虑重新初始化物理引擎
|
physics = simulatorConfig.physics.copy(
|
||||||
|
totalDistance = totalDistance,
|
||||||
|
duration = duration,
|
||||||
|
maxVelocity = maxVelocity,
|
||||||
|
minVelocity = (maxVelocity * 0.45).coerceAtLeast(0.5)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
physicsEngine = createPhysicsEngine()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setPhysicsModelParams(
|
||||||
|
minVelocity: Double,
|
||||||
|
sampleStepSeconds: Double = 1.0,
|
||||||
|
modelMaxAccelerationMps2: Double = 1.2,
|
||||||
|
seed: Long? = null
|
||||||
|
) {
|
||||||
|
simulatorConfig = simulatorConfig.copy(
|
||||||
|
physics = simulatorConfig.physics.copy(
|
||||||
|
minVelocity = minVelocity,
|
||||||
|
sampleStepSeconds = sampleStepSeconds,
|
||||||
|
modelMaxAccelerationMps2 = modelMaxAccelerationMps2,
|
||||||
|
seed = seed
|
||||||
|
)
|
||||||
|
)
|
||||||
|
physicsEngine = createPhysicsEngine()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -128,7 +220,12 @@ class TrajectorySimulator(route: List<MetaCoordinate>) {
|
|||||||
gpsErrorStdDev: Double,
|
gpsErrorStdDev: Double,
|
||||||
driftWeight: Double
|
driftWeight: Double
|
||||||
) {
|
) {
|
||||||
// TODO: 实现参数设置逻辑
|
simulatorConfig = simulatorConfig.copy(
|
||||||
// 可考虑动态调整噪声引擎参数
|
noise = simulatorConfig.noise.copy(
|
||||||
|
gpsErrorStdDev = gpsErrorStdDev,
|
||||||
|
driftWeight = driftWeight
|
||||||
|
)
|
||||||
|
)
|
||||||
|
noiseProcessor = createNoiseProcessor()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -40,8 +40,14 @@ interface NoiseEngine {
|
|||||||
* ↓
|
* ↓
|
||||||
* NoisyCoordinate (添加了噪声)
|
* NoisyCoordinate (添加了噪声)
|
||||||
*/
|
*/
|
||||||
class NoiseProcessor {
|
class NoiseProcessor(
|
||||||
private val gpsNoiseEngine = GpsNoiseEngine()
|
gpsErrorStdDev: Double = 0.00002,
|
||||||
|
driftWeight: Double = 0.3
|
||||||
|
) {
|
||||||
|
private val gpsNoiseEngine = GpsNoiseEngine(
|
||||||
|
gpsErrorStdDev = gpsErrorStdDev,
|
||||||
|
driftWeight = driftWeight
|
||||||
|
)
|
||||||
// 预留其他噪声引擎
|
// 预留其他噪声引擎
|
||||||
// private val velocityNoiseEngine = VelocityNoiseEngine()
|
// private val velocityNoiseEngine = VelocityNoiseEngine()
|
||||||
// private val accelerationNoiseEngine = AccelerationNoiseEngine()
|
// private val accelerationNoiseEngine = AccelerationNoiseEngine()
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user