[chronojump] Added sprint test using encoder race.
- From: Xavier Padullés <xpadulles src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [chronojump] Added sprint test using encoder race.
- Date: Mon, 16 Apr 2018 16:29:51 +0000 (UTC)
commit ae44bbc045e77575827f09e0fe050ea9265b61fa
Author: Xavier Padullés <x padulles gmail com>
Date: Mon Apr 16 18:27:14 2018 +0200
Added sprint test using encoder race.
r-scripts/sprintEncoder.R | 159 ++++++++++++++++++++++++++++++++++++++++++
r-scripts/sprintPhotocells.R | 40 ++++++++++-
r-scripts/sprintUtil.R | 43 +++++++-----
3 files changed, 220 insertions(+), 22 deletions(-)
---
diff --git a/r-scripts/sprintEncoder.R b/r-scripts/sprintEncoder.R
new file mode 100644
index 0000000..542c87c
--- /dev/null
+++ b/r-scripts/sprintEncoder.R
@@ -0,0 +1,159 @@
+#
+# This file is part of ChronoJump
+#
+# ChronoJump is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# ChronoJump is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Copyright (C) 2018 Xavier Padullés <x padulles gmail com>
+
+#-------------- get params -------------
+args <- commandArgs(TRUE)
+
+tempPath <- args[1]
+optionsFile <- paste(tempPath, "/Roptions.txt", sep="")
+pngFile <- paste(tempPath, "/sprintGraph.png", sep="")
+
+#-------------- scan options file -------------
+options <- scan(optionsFile, comment.char="#", what=character(), sep="\n")
+
+#-------------- load sprintUtil.R -------------
+#options[1] is scriptsPath
+source(paste(options[1], "/sprintUtil.R", sep=""))
+
+assignOptions <- function(options) {
+ return(list(
+ scriptsPath = options[1],
+ filename = options[2],
+ mass = as.numeric(options[3]),
+ personHeight = as.numeric(options[4]),
+ tempC = as.numeric(options[5]),
+ testLength = as.numeric(options[6]),
+ os = options[7],
+ graphWidth = as.numeric(options[8]),
+ graphHeight = as.numeric(options[9])
+ ))
+}
+
+#-------------- assign options -------------
+op <- assignOptions(options)
+
+getSprintFromEncoder <- function(filename, testLength)
+{
+ encoderCarrera = read.csv2(file = filename, sep = ";")
+ colnames(encoderCarrera) = c("displacement", "time")
+ totalTime = encoderCarrera$time/1E6 #Converting microseconds to seconds
+ elapsedTime = diff(c(0,totalTime)) #The elapsed time between each sample
+
+ #The encoder can be used with both loose ends of the rope. This means that the encoder can rotate
+ #in both directions. We considre always the speed as positive.
+ if(mean(encoderCarrera$displacement) < 0)
+ encoderCarrera$displacement = -encoderCarrera$displacement
+ diameter = 0.16 #Diameter of the pulley
+ #encoderCarrera$displacement = encoderCarrera$displacement * 2 * pi * diameter / 200
+ #In 30m there are 12267 pulses.
+ #TODO: measure this several times to have an accurate value
+ encoderCarrera$displacement = encoderCarrera$displacement * 30 / 12267
+ position = cumsum(encoderCarrera$displacement)
+ speed = encoderCarrera$displacement / elapsedTime
+ accel = c(0,diff(speed)/elapsedTime[2:length(elapsedTime)])
+
+ #Finding when the sprint starts
+ trimmingSamples = getTrimmingSamples(totalTime, position, speed, accel, testLength)
+
+ #Zeroing time to the initial acceleration sample
+ time = totalTime - totalTime[trimmingSamples$start]
+ #Zeroing position to the initial acceleration sample
+ position = position - position[trimmingSamples$start]
+ data = data.frame(time = time[trimmingSamples$start:trimmingSamples$end], speed =
speed[trimmingSamples$start:trimmingSamples$end])
+ model = nls(speed ~ Vmax*(1-exp(-K*time)), data,
+ start = list(Vmax = max(speed), K = 1), control=nls.control(warnOnly=TRUE))
+ Vmax =summary(model)$coeff[1,1]
+ K = summary(model)$coeff[2,1]
+ return(list(Vmax = Vmax, K = K,
+ time = time, rawPosition = position, rawSpeed = speed, rawAccel = accel,
+ startSample = trimmingSamples$start, endSample = trimmingSamples$end, testLength =
testLength))
+}
+
+drawSprintFromEncoder <- function(sprint, sprintDynamics, title = "Test graph")
+{
+ #Plotting position
+ par(mar = c(7, 4, 5, 6.5))
+ plot(sprint$time[sprint$startSample:sprint$endSample],
sprint$rawPosition[sprint$startSample:sprint$endSample],
+ main = paste(50, "PPR"), xlab = "Time (s)", ylab = "Position (m)", type = "l")
+ print(sprint$time)
+ print(sprint$rawPosition)
+ raceTime = sprint$time[sprint$endSample] #TODO: interpolate values as in force sensor.
+ abline(v = raceTime)
+ mtext(side = 3, at = raceTime, text = paste(sprint$testLength, "m", sep=""))
+ mtext(side = 1, at = raceTime, text = paste(round(raceTime, digits = 3), "s", sep=""))
+
+ # Getting values from the exponential model. Used for numerical calculations
+ time.fitted = seq(0,sprint$time[length(sprint$time)], by = 0.01)
+ v.fitted=sprintDynamics$Vmax.fitted*(1-exp(-sprintDynamics$K.fitted*time.fitted))
+
+ #Calculating the fitted dynamics
+ # a.fitted = Vmax*K*exp(-K*time)
+ # f.fitted = Mass*a.fitted + Ka*(v.fitted - Vw)^2
+ # p.fitted = f.fitted * v.fitted
+
+ #Plotting rawSpeed
+ par(new = TRUE)
+ plot(sprint$time[sprint$startSample:sprint$endSample],
sprint$rawSpeed[sprint$startSample:sprint$endSample],
+ type = "l", col = "green", axes = FALSE, xlab = "", ylab = "")
+
+ #Plotting fitted speed
+ lines(time.fitted, v.fitted, col = "grey")
+ axis(side = 4)
+
+ #Plotting rawAccel
+ par(new = TRUE)
+ plot(sprint$time[sprint$startSample:sprint$endSample],
sprint$rawAccel[sprint$startSample:sprint$endSample],
+ type = "l", col = "magenta", axes = FALSE, xlab ="", ylab = "")
+}
+
+#Detecting where the sprint start and stops
+getTrimmingSamples <- function(totalTime, position, speed, accel, testLength)
+{
+ print(totalTime)
+ #The analysis starts two samples before the maximum acceleration
+ start = which.max(accel)
+ while(speed[start] > 1)
+ {
+ start = start -1
+ }
+
+ #Zeroing time to the initial acceleration sample
+ totalTime = totalTime - totalTime[start]
+ #Zeroing position to the initial acceleration sample
+ position = position - position[start]
+
+ #Detecting when starts the braking phase
+ end = which.min(abs(position - testLength))
+ print(paste("endTime = ",totalTime[end], "s"))
+ print(paste("endPosition = ",position[end], "m"))
+ return(list(start = start, end = end ))
+}
+
+testEncoderCJ <- function(filename, testLength, mass, personHeight, tempC)
+{
+ sprint = getSprintFromEncoder(filename, testLength)
+ sprintDynamics = getDynamicsFromSprint(K = sprint$K, Vmax = sprint$Vmax, mass, tempC, personHeight)
+ print(paste("K =",sprintDynamics$K.fitted, "Vmax =", sprintDynamics$Vmax.fitted))
+ drawSprintFromEncoder(sprint = sprint, sprintDynamics = sprintDynamics, title = "Testing graph")
+}
+
+prepareGraph(op$os, pngFile, op$graphWidth, op$graphHeight)
+testEncoderCJ(op$filename, op$testLength, op$mass, op$personHeight, op$tempC)
+endGraph()
+
diff --git a/r-scripts/sprintPhotocells.R b/r-scripts/sprintPhotocells.R
index 2667d0b..c6baaef 100644
--- a/r-scripts/sprintPhotocells.R
+++ b/r-scripts/sprintPhotocells.R
@@ -175,10 +175,28 @@ drawSprintFromPhotocells <- function(sprintDynamics, splitTimes, positions, titl
paste("pmax =", round(sprintDynamics$pmax.rel.fitted, digits = 2), "W/Kg")),
text.col = c("black", "black", "green", "blue", "red"))
- exportData = list(Mass = sprintDynamics$Mass, Height = sprintDynamics$Height, Temperature =
sprintDynamics$Temperature, Vw = sprintDynamics$Vw, Ka = sprintDynamics$Ka, K.fitted =
sprintDynamics$K.fitted, Vmax.fitted = sprintDynamics$Vmax,
- amax.fitted = sprintDynamics$amax.fitted, fmax.fitted =
sprintDynamics$fmax.fitted, fmax.rel.fitted = sprintDynamics$fmax.rel.fitted, sfv.fitted =
sprintDynamics$sfv.fitted, sfv.rel.fitted = sprintDynamics$sfv.rel.fitted,
- pmax.fitted = sprintDynamics$pmax.fitted, pmax.rel.fitted =
sprintDynamics$pmax.rel.fitted, tpmax.fitted = sprintDynamics$tpmax.fitted, F0 = sprintDynamics$F0, F0.rel =
sprintDynamics$F0.rel, V0 = sprintDynamics$V0,
- sfv.lm = sprintDynamics$sfv.lm, sfv.rel.lm = sprintDynamics$sfv.rel.lm, pmax.lm =
sprintDynamics$pmax.lm, pmax.rel.lm = sprintDynamics$pmax.rel.lm)
+ exportData = list(Mass = sprintDynamics$Mass,
+ Height = sprintDynamics$Height,
+ Temperature = sprintDynamics$Temperature,
+ Vw = sprintDynamics$Vw,
+ Ka = sprintDynamics$Ka,
+ K.fitted = sprintDynamics$K.fitted,
+ Vmax.fitted = sprintDynamics$Vmax,
+ amax.fitted = sprintDynamics$amax.fitted,
+ fmax.fitted = sprintDynamics$fmax.fitted,
+ fmax.rel.fitted = sprintDynamics$fmax.rel.fitted,
+ sfv.fitted = sprintDynamics$sfv.fitted,
+ sfv.rel.fitted = sprintDynamics$sfv.rel.fitted,
+ sfv.lm = sprintDynamics$sfv.lm,
+ sfv.rel.lm = sprintDynamics$sfv.rel.lm,
+ pmax.fitted = sprintDynamics$pmax.fitted,
+ pmax.rel.fitted = sprintDynamics$pmax.rel.fitted,
+ tpmax.fitted = sprintDynamics$tpmax.fitted,
+ F0 = sprintDynamics$F0,
+ F0.rel = sprintDynamics$F0.rel,
+ V0 = sprintDynamics$V0,
+ pmax.lm = sprintDynamics$pmax.lm,
+ pmax.rel.lm = sprintDynamics$pmax.rel.lm)
write.csv2(exportData, file = paste(tempPath, "/sprintResults.csv", sep = ""))
}
@@ -192,6 +210,20 @@ testPhotocellsCJ <- function(positions, splitTimes, mass, personHeight, tempC)
drawSprintFromPhotocells(sprintDynamics = sprintDynamics, splitTimes, positions, title = "Testing
graph")
}
+assignOptions <- function(options) {
+ return(list(
+ scriptsPath = options[1],
+ positions = as.numeric(unlist(strsplit(options[2], "\\;"))),
+ splitTimes = as.numeric(unlist(strsplit(options[3], "\\;"))),
+ mass = as.numeric(options[4]),
+ personHeight = as.numeric(options[5]),
+ tempC = as.numeric(options[6]),
+ os = options[7],
+ graphWidth = as.numeric(options[8]),
+ graphHeight = as.numeric(options[9])
+ ))
+}
+
#----- execute code
prepareGraph(op$os, pngFile, op$graphWidth, op$graphHeight)
diff --git a/r-scripts/sprintUtil.R b/r-scripts/sprintUtil.R
index 782a553..2b105d8 100644
--- a/r-scripts/sprintUtil.R
+++ b/r-scripts/sprintUtil.R
@@ -68,10 +68,31 @@ getDynamicsFromSprint <- function(K, Vmax, Mass, Temperature = 25, Height , Vw =
pmax.rel.fitted = pmax.fitted / Mass
tpmax.fitted = log(2) / K # Obtained from P'(t) = 0
- return(list(Mass = Mass, Height = Height, Temperature = Temperature, Vw = Vw, Ka = Ka, K.fitted = K,
Vmax.fitted = Vmax,
- amax.fitted = amax.fitted, fmax.fitted = fmax.fitted, fmax.rel.fitted = fmax.rel.fitted,
sfv.fitted = sfv.fitted, sfv.rel.fitted = sfv.rel.fitted,
- pmax.fitted = pmax.fitted, pmax.rel.fitted = pmax.rel.fitted, tpmax.fitted =
tpmax.fitted, F0 = F0, F0.rel = F0.rel, V0 = V0,
- sfv.lm = sfv.lm, sfv.rel.lm = sfv.rel.lm, pmax.lm = pmax.lm, pmax.rel.lm = pmax.rel.lm,
v.fitted = v.fitted, a.fitted = a.fitted, f.fitted = f.fitted, p.fitted = p.fitted ))
+ return(list(Mass = Mass,
+ Height = Height, Temperature = Temperature,
+ Vw = Vw,
+ Ka = Ka,
+ K.fitted = K,
+ Vmax.fitted = Vmax,
+ amax.fitted = amax.fitted,
+ fmax.fitted = fmax.fitted,
+ fmax.rel.fitted = fmax.rel.fitted,
+ sfv.fitted = sfv.fitted,
+ sfv.rel.fitted = sfv.rel.fitted,
+ pmax.fitted = pmax.fitted,
+ pmax.rel.fitted = pmax.rel.fitted,
+ tpmax.fitted = tpmax.fitted,
+ F0 = F0,
+ F0.rel = F0.rel,
+ V0 = V0,
+ sfv.lm = sfv.lm,
+ sfv.rel.lm = sfv.rel.lm,
+ pmax.lm = pmax.lm,
+ pmax.rel.lm = pmax.rel.lm,
+ v.fitted = v.fitted,
+ a.fitted = a.fitted,
+ f.fitted = f.fitted,
+ p.fitted = p.fitted ))
}
#Finds the time correspondig to a given position in the formula x(t) = Vmax*(t + (1/K)*exp(-K*t)) -Vmax - 1/K
@@ -105,17 +126,3 @@ endGraph <- function()
{
dev.off()
}
-
-assignOptions <- function(options) {
- return(list(
- scriptsPath = options[1],
- positions = as.numeric(unlist(strsplit(options[2], "\\;"))),
- splitTimes = as.numeric(unlist(strsplit(options[3], "\\;"))),
- mass = as.numeric(options[4]),
- personHeight = as.numeric(options[5]),
- tempC = as.numeric(options[6]),
- os = options[7],
- graphWidth = as.numeric(options[8]),
- graphHeight = as.numeric(options[9])
- ))
-}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]