library(trajr)
context("Velocity and acceleration tests")
test_that("Basic velocity", {
# Crude test that it doesn't crash and returns the expected number of values
set.seed(1)
n <- 10
# Argument to TrajGenerate is number of steps, whereas we want n to be number
# of points, i.e. 1 more than number of steps
trj <- TrajGenerate(n = n - 1)
vel <- TrajVelocity(trj)
expect_equal(length(vel), n)
expect_true(inherits(vel, "complex"))
expect_equal(attr(vel, "trj"), trj)
# Expect 1st and last to be NA, no others
expect_true(is.na(vel[1]))
expect_true(is.na(vel[n]))
expect_equal(sum(is.na(vel)), 2)
})
test_that("velocity", {
# Test returned values are as expected.
# Simple trajectory, constant velocity in x, exponentially increasing in y
x <- 1:10
y <- x ^ 2
trj <- TrajFromCoords(data.frame(x, y), fps = 1)
vel <- TrajVelocity(trj)
# Discard first and last elements - we know they are NA (tested above)
vel <- vel[2:(length(vel) - 1)]
# X velocities should all be 1
expect_true(all(Re(vel) == 1))
# Y velocities should be increasing linearly
expect_true(all(Im(vel) == seq(4, length.out = length(vel), by = 2)))
})
test_that("Basic acceleration", {
set.seed(1)
n <- 10
# Argument to TrajGenerate is number of steps, whereas we want n to be number
# of points, i.e. 1 more than number of steps
trj <- TrajGenerate(n = n - 1)
acc <- TrajAcceleration(trj)
expect_equal(length(acc), n)
expect_true(inherits(acc, "complex"))
expect_equal(attr(acc, "trj"), trj)
# Expect 1st and last to be NA, no others
expect_true(is.na(acc[1]))
expect_true(is.na(acc[n]))
expect_equal(sum(is.na(acc)), 2)
})
test_that("Acceleration", {
# Test returned values are as expected.
# Simple trajectory, constant velocity in x, exponentially increasing in y
x <- 1:10
y <- x ^ 2
trj <- TrajFromCoords(data.frame(x, y), fps = 1)
acc <- TrajAcceleration(trj)
# Discard first and last elements - we know they are NA (tested above)
acc <- acc[2:(length(acc) - 1)]
# X acceleration should all be 0 (constant velocity)
expect_true(all(Re(acc) == 0))
# Y acceleration should all be 2 (constant but non-zero acceleration)
expect_true(all(Im(acc) == 2))
})
test_that("Variable step times", {
# Simple trajectory, constant step length of 5, speed oscillates between 1 & 5
x <- 1:10 * 3
y <- 1:10 * 4
times <- cumsum(rep(c(1, 5), times = 5))
trj <- TrajFromCoords(data.frame(x, y, times), timeCol = 3)
# Calculate velocity using forward differences
fvel <- TrajVelocity(trj, diff = "forward")
expect_true(is.na(fvel[length(fvel)]))
# Discard last element
vel <- fvel[1:(length(fvel) - 1)]
# Speeds should match those from TrajDerivates since the trajectory is 1-dimensional and we've used forward differences
expect_true(all(Mod(vel) == TrajDerivatives(trj)$speed))
# Backward should be the same as forward except NA is first rather than last element
bvel <- TrajVelocity(trj, diff = "backward")
expect_true(is.na(bvel[1]))
expect_true(all(bvel[2:length(bvel)] == vel))
})
test_that("acc sanity", {
# Perform a sanity check: simple implementation of acceleration by central
# differences from fixed step times should yield the same result as
# TrajAcceleration applied to fixed step times
set.seed(2)
n <- 100
trj <- TrajGenerate(n = n - 1)
acc <- TrajAcceleration(trj)
# Recalculate using central diffs
dt <- mean(diff(trj$time))
ax <- stats::filter(trj$x, c(1, -2, 1)) / dt ^ 2
ay <- stats::filter(trj$y, c(1, -2, 1)) / dt ^ 2
expect_equal(as.numeric(Re(acc)), as.numeric(ax))
expect_equal(as.numeric(Im(acc)), as.numeric(ay))
})
test_that("Variable steps acc", {
# Step lengths are equal, but time decreases so trajectory is accelerating
x <- c(1, 1, 1, 1, 1)
y <- 1:5 * 8
times <- cumsum(c(0, 8, 4, 2, 1))
trj <- TrajFromCoords(data.frame(x, y, times), timeCol = 3)
# Integrating velocity should give us distance travelled at each step
vel <- TrajVelocity(trj, diff = "forward")
vel <- head(vel, -1) # Remove trailing NA
dx <- Re(vel) * diff(times)
expect_equal(dx, diff(x))
dy <- Im(vel) * diff(times)
expect_equal(dy, diff(y))
# Compare acceleration to hand-calculated acceleration
acc <- TrajAcceleration(trj)
acc <- na.omit(acc)
expect_equal(as.numeric(Re(acc)), rep(0, 3))
# Speeds should be 1, 2, 4, 8
expect_equal(Im(vel), c(1, 2, 4, 8))
# Acceleration should be (diffs in speed) / (diffs in times of step centres)
expect_equal(as.numeric(Im(acc)), c(1, 2, 4) / c(6, 3, 1.5))
})
test_that("velocity & speed", {
set.seed(5)
trj <- TrajGenerate()
# Compare speed from TrajDerivatives & TrajVelocity
drv <- TrajDerivatives(trj)
vel <- TrajVelocity(trj, diff = "backward")
vspeed <- data.frame(speed = Mod(vel), speedTimes = trj$time)
vspeed <- na.omit(vspeed)
expect_equal(drv$speed, vspeed$speed)
expect_equal(drv$speedTimes, vspeed$speedTimes)
# Try a different, log trajectory
trj <- TrajGenerate(n = 10000, linearErrorDist = rcauchy)
drv <- TrajDerivatives(trj)
vel <- TrajVelocity(trj, diff = "backward")
vspeed <- na.omit(data.frame(speed = Mod(vel), speedTimes = trj$time))
expect_equal(drv$speed, vspeed$speed)
expect_equal(drv$speedTimes, vspeed$speedTimes)
trj <- TrajGenerate(50000, angularErrorDist = function(n) runif(n, -pi, pi))
drv <- TrajDerivatives(trj)
vel <- TrajVelocity(trj, diff = "backward")
vspeed <- na.omit(data.frame(speed = Mod(vel), speedTimes = trj$time))
expect_equal(drv$speed, vspeed$speed)
expect_equal(drv$speedTimes, vspeed$speedTimes)
})
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.