Disclaimer: All data and fit curves shown in this notebook are fictional.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
see the readme.md file in the root directory. https://github.com/fsaer/tirefittingr
Make sure you have downloaded and installed the package if you haven't already. Installing only needs to be done once on a computer.
install.packages("devtools") devtools::install_github("fsaer/tirefittingr") # if there's bugs, you can download the latest release instead # Replace X.X.X with the latest version number from # https://github.com/fsaer/tirefittingr/releases # devtools::install_github("fsaer/tirefittingr@X.X.X") install.packages("plotly") #now is also the time to install plotly if you haven't already
This must be done every r-session, so this code is often at the top of every script.
library(tirefittingr) library(plotly)
We are going to speed up the solver a bit for this example. This will reduce the quality of the fit.
options( tirefittingr.iParallelCores = 1, tirefittingr.iEvolIterMax = 30, tirefittingr.iDataPoints = 3000, tirefittingr.sSavePlotPath = FALSE, tirefittingr.bPlotRunConditions = TRUE)
At a minimum, we need to set the options telling the program whether we are fitting FX or FY Pure.
#Required options #options(tirefittingr.sdfStartPop = "dfStartParFY") #options(tirefittingr.sfFittingFunction = "FYPurePacejka2002") # To save time, the function below will set the above options for us, as # well as a preprocessing function and plotting function specific to FY. setFYPure2002() # #If we wanted to analyze FX, we could do the following # setFXPure2002.wIA()
Now we are ready to use the tire fitting function.
For this example, we are using 2 built in data sets of fictious data
dfFitSummary = fitTires(c("ABCrun1LatPreProccessed", "ABCrun2LatPreProccessed"))
After fitting, we can look at the output plots. In the run conditions plots, we can check that our tire got up to temperature, that it actually contains IA sweeps, and the pressure is what we expected.
In the goodness of fit plots, we can see how closely our fitted curve matches the raw data.
Let's see the full output by clicking on dfFitSummary
in the top right
"Environment" tab, or by running View(dfFitSummary)
in the console.
Running fitTires() without any arguments will open a dialog box to pick files. Make sure if you have setFYPure2002, then you are selecting FY files or vice versa!
First we will clear the previous options. This will take longer to solve, but we will get a better fit.
clearTirefittingrOptions() setFYPure2002() #setFXPure2002.wIA() dfFitSummary = fitTires()
fitTires() can accept file paths or vectors of file paths.
Make a vector of file paths with the c()
function.
setFYPure2002() #setFXPure2002.wIA() #Always use forward slashes in file paths in R! dfFitSummary = fitTires("C:/users/fsaer/data/rawData1.dat") dfFitSummary = fitTires(c("C:/users/fsaer/data/rawData1.dat", "C:/users/fsaer/data/rawData2.dat"))
We can also pass in a vector of names of the tire files in, to help us remember what they are later. These names will show up in the plots too.
setFYPure2002() #setFXPure2002.wIA() dfFitSummary = fitTires("ABCrun1LatPreProccessed", "ABC Tire on 13in Rim") dfFitSummary = fitTires(c("ABCrun1LatPreProccessed", "ABCrun2LatPreProccessed"), c("ABC Tire1 13in rim 10 psi", "ABC Tire2 10in rim 10psi" ))
When fitTires() runs with default settings, it will ask the user for a folder
to save the output to.
We can also save the output to a file with the following.
#Always use forward slashes in file paths in R! write.csv(dfFitSummary, "C:/TireFittingSummary.csv")
We could have automatically saved to a csv file by setting option tirefittingr.sSummaryExportPath equal to a string of a folder path before running fitTires().
print(getwd()) #get the working directory #enter a full file path using forward slashes / not backslashes. #options(tirefittingr.sSummaryExportPath = "C:/users") options(tirefittingr.sSummaryExportPath = getwd()) fitTires()
For a full list of options see the help file for the fitTires() function:
?fitTires
TTC data often comes with multiple pressures within a data file.
While a better splitting app is currently being developed, the splitTireDataAndSave function works. It can do multiple files very quickly. The new split files will be saved in the same folder that the original files were in.
The function returns a list of the new file names, which can be passed into fitTires() for analysis.
#Open window to pick files lRunNamesSplit = splitTireDataAndSave(P = 6.894*c(8,10,12,14), verbose = TRUE) # #Input file paths, use forward slashes in file paths in R! #lRunNamesSplit = splitTireDataAndSave(c("C:/file1.dat", "C:/file2.dat"), P = 6.894*c(8,10,12,14), verbose = TRUE)
Feel free to switch to matlab or excel/vba from here. The equations used are available on github at fsaer/tirefittingr/R/Magic.R or https://github.com/fsaer/tirefittingr/blob/master/R/Magic.R.
Now let's compare our two tires in basic FY vs Slip Angle plots.
First, we will decide what sweeps of parameters will will be plotting.
Our pacejka equation requires SA
, FZ
, and IA
, so we have to include them.
#Using the results from: # setFYPure2002() # dfFitSummary = fitTires(c("ABCrun1LatPreProccessed", "ABCrun2LatPreProccessed")) SAplot = seq(from = -12, to = 12, by = 0.05) #Slip angle in degrees IAPlot = 0 #inclination angle in degrees # FZ0Plot = -1600 #Nominal FZ value. -1600 is a good number. FZPlot = c(-250, -750, -1200) #FZ in Newtons IAPlot = 0
The easiest way to create data frames that we can plot is by using the createFitDataFrame function. This function will evaluate our fitting function, in this case FYPurePAcejka2002, at every different combination of our SA, IA, and FZ inputs.
We can learn more about this function with
?createFitDataFrame
After creating our data we'll create a matrix that is easy to plot
mGridPlot = createFitDataFrame(FYPurePacejka2002, "parameters", SA = SAplot, FZ = FZPlot, IA = IAPlot, parameters = dfFitSummary[1, 9:ncol(dfFitSummary)])
Create a blank plot and set the legend at the top.
myPlot = plotly::layout(plot_ly(), legend = list(orientation = 'h', x = 0, y = 1.15))
Add markers to the plot
myPlot = add_markers(myPlot, data = mGridPlot, x = ~SA, y = ~FY, name = dfFitSummary[1, 1], marker = list(color = "blue")) show(myPlot)
Let's create a second data frame for our second data set, then plot it.
#Create a matrix that is easy to plot mGridPlot2 = createFitDataFrame(FYPurePacejka2002, "parameters", SA = SAplot, FZ = FZPlot, IA = IAPlot, parameters = dfFitSummary[2, 9:ncol(dfFitSummary)]) #Add markers to the plot myPlot = add_markers(myPlot, data = mGridPlot2, x = ~SA, y = ~FY, name = dfFitSummary[2, 1], marker = list(color = "red")) show(myPlot)
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.