Sounds like a fun problem you're working on.
I guess a question is whether the sensors are making errors serially, or whether the errors (especially big ones) are independently distributed. Is it actually posing a problem for your robot?
I wrote a little test (below) which compares using a mean, median, weighted mean (using student's t probability of a t score from the observation mean), weighted mean (using the normal probability of a z score from the observation, which should punish outliers more), a trimmed mean, and a geometric mean. The test shows (unsurprisingly) that the arithmetic mean is most efficient in large samples, though not necessarily the best in individual samples with outliers. So again it comes to the question of the distribution of your outliers. If they're not serially correlated for a particular sensor then perhaps a good work-around is to base less of the robot's steering on the current observation, but perhaps on a couple of past observations also.
Anyhow, here's my R code, which gives you the RMSE for the six different measures. The weighting is pretty ad-hoc, but I've had too much wine to think about it too much.
Cheers,
Jim
library(psych)
# Real parameter = 4.45
compare <- function(){
param <- 4.45
# standard deviation = 0.3
sd <- 0.3
# generate 1000 observations of the param
obs <- param + sd * rnorm(1000,0,1)
smpl.sd <- sd(sample(obs, 30, replace = TRUE))
# Now we randomly sample five observations, and try several different methods,
# finally comparing the different methods in terms of their RMSE.
smpl.mean <- rep(NA, 100)
smpl.med <- rep(NA, 100)
smpl.wmt <- rep(NA, 100)
smpl.wmp <- rep(NA, 100)
smpl.tm <- rep(NA, 100)
smpl.gm <- rep(NA, 100)
for(i in 1:100){
draw <- sample(obs, 5,replace = TRUE)
smpl.mean[i] <- mean(draw)
smpl.med[i] <- median(draw)
t <- (draw - smpl.mean[i])/(smpl.sd/sqrt(length(draw)))
p.t <- ifelse(t>0, pt(t,df = length(draw)), pt(t,df = length(draw), lower.tail = FALSE))
smpl.wmt[i] <- weighted.mean(draw, p.t)
z <- (draw - smpl.mean[i])/smpl.sd
p.z <- ifelse(z>0, pnorm(z), pnorm(z, lower.tail = FALSE) )
smpl.wmp[i] <- weighted.mean(draw, p.z)
smpl.tm[i] <- mean(sort(draw)[2:4])
smpl.gm[i] <- geometric.mean(draw)
}
working <- sqrt((cbind(smpl.mean, smpl.med, smpl.wmt, smpl.wmp, smpl.tm, smpl.gm)-param)^2)
rmse <- colMeans(working)
return(rmse)
}
rmses <- array(NA, c(1000,6))
for (i in 1:100){
rmses[i, ] = t(compare())
}
colMeans(rmses)