1- plotProfile <- function (profileName , inverted = FALSE , wheelbaseDiameter , centerToFront , centerToBack , centerToSide , startY = 0 , startPos = c(- 1 ,- 1 ,- 1 ,- 1 ,- 1 ), usePosition = TRUE ){
1+ plotProfile <- function (profileName , inverted = FALSE , wheelbaseDiameter , centerToFront , centerToBack , centerToSide , startY = 0 , startPos = c(- 1 ,- 1 ,- 1 ,- 1 ,- 1 , - 1 ), usePosition = TRUE ){
22 left <- read.csv(paste(" ../calciferLeft" ,profileName ," Profile.csv" ,sep = " " ), header = FALSE )
33 right <- read.csv(paste(" ../calciferRight" ,profileName ," Profile.csv" ,sep = " " ), header = FALSE )
44 startingCenter <- c(startY , centerToBack )
@@ -11,17 +11,18 @@ plotProfile <- function(profileName, inverted = FALSE, wheelbaseDiameter, center
1111 # Position,Velocity,Delta t, Elapsed time
1212 left $ V4 <- (0 : (length(left $ V1 )- 1 ))* left $ V3 [1 ]
1313 right $ V4 <- (0 : (length(right $ V1 )- 1 ))* right $ V3 [1 ]
14- # Time, Left X, Left Y, Right X, Right Y
15- out <- array (dim = c(length(left $ V1 ),5 ))
16- if (identical(startPos , c(- 1 ,- 1 ,- 1 ,- 1 ,- 1 ))){
17- out [1 ,]<- c(0 , startingCenter [2 ], (startingCenter [1 ]+ wheelbaseDiameter / 2 . ), startingCenter [2 ], (startingCenter [1 ]- wheelbaseDiameter / 2 . ))
14+ # Time, Left X, Left Y, Right X, Right Y, Angle
15+ out <- array (dim = c(length(left $ V1 ),6 ))
16+ if (identical(startPos , c(- 1 ,- 1 ,- 1 ,- 1 ,- 1 , - 1 ))){
17+ out [1 ,]<- c(0 , startingCenter [2 ], (startingCenter [1 ]+ wheelbaseDiameter / 2 . ), startingCenter [2 ], (startingCenter [1 ]- wheelbaseDiameter / 2 . ), 0 )
1818 } else {
1919 out [1 ,]<- startPos
2020 }
2121
2222 for (i in 2 : length(left $ V4 )){
2323 # Get the angle the robot is facing.
24- perpendicular <- angleBetween(leftX = out [i - 1 ,2 ], leftY = out [i - 1 ,3 ], rightX = out [i - 1 ,4 ], rightY = out [i - 1 ,5 ])- pi / 2
24+ perpendicular <- out [i - 1 ,6 ]
25+ print(perpendicular )
2526
2627 # Add the change in time
2728 out [i ,1 ] <- out [i - 1 ,1 ]+ left $ V3 [i ]
@@ -41,56 +42,42 @@ plotProfile <- function(profileName, inverted = FALSE, wheelbaseDiameter, center
4142 deltaRight <- - deltaRight
4243 }
4344
45+ diffTerm <- deltaRight - deltaLeft
4446 # So in this next part, we figure out the turning center of the robot
4547 # and the angle it turns around that center. Note that the turning center is
4648 # often outside of the robot.
4749
4850 # Calculate how much we turn first, because if theta = 0, turning center is infinitely far away and can't be calcualted.
49- theta <- (deltaLeft - deltaRight )/ wheelbaseDiameter
51+ theta <- diffTerm / wheelbaseDiameter
52+
53+ out [i ,6 ] <- out [i - 1 ,6 ]+ theta
5054
5155 # If theta is 0, we're going straight and need to treat it as a special case.
5256 if (identical(theta , 0 )){
53-
54- # If inverted, swap which wheel gets which input
55- if (inverted ){
56- out [i , 2 ] <- out [i - 1 ,2 ]+ deltaRight * cos(perpendicular )
57- out [i , 3 ] <- out [i - 1 ,3 ]+ deltaRight * sin(perpendicular )
58- out [i , 4 ] <- out [i - 1 ,4 ]+ deltaLeft * cos(perpendicular )
59- out [i , 5 ] <- out [i - 1 ,5 ]+ deltaLeft * sin(perpendicular )
60- } else {
61- out [i , 2 ] <- out [i - 1 ,2 ]+ deltaLeft * cos(perpendicular )
62- out [i , 3 ] <- out [i - 1 ,3 ]+ deltaLeft * sin(perpendicular )
63- out [i , 4 ] <- out [i - 1 ,4 ]+ deltaRight * cos(perpendicular )
64- out [i , 5 ] <- out [i - 1 ,5 ]+ deltaRight * sin(perpendicular )
65- }
57+ out [i , 2 ] <- out [i - 1 ,2 ]+ deltaLeft * cos(perpendicular )
58+ out [i , 3 ] <- out [i - 1 ,3 ]+ deltaLeft * sin(perpendicular )
59+ out [i , 4 ] <- out [i - 1 ,4 ]+ deltaRight * cos(perpendicular )
60+ out [i , 5 ] <- out [i - 1 ,5 ]+ deltaRight * sin(perpendicular )
6661 } else {
6762
6863 # We do this with sectors, so this is the radius of the turning circle for the
6964 # left and right sides. They just differ by the diameter of the wheelbase.
70- rightR <- (wheelbaseDiameter / 2 ) * (deltaLeft + deltaRight ) / ( deltaLeft - deltaRight ) - wheelbaseDiameter / 2
71- leftR <- rightR + wheelbaseDiameter
65+ rightR <- (wheelbaseDiameter / 2 ) * (deltaRight + deltaLeft ) / diffTerm + wheelbaseDiameter / 2
66+ leftR <- rightR - wheelbaseDiameter
7267
7368 # This is the angle for the vector pointing towards the new position of each
7469 # wheel.
7570 # To understand why this formula is correct, overlay isoclese triangles on the sectors
76- vectorTheta <- perpendicular + theta / 2
71+ vectorTheta <- ( out [ i - 1 , 6 ] + out [ i , 6 ]) / 2
7772
7873 # The is the length of the vector pointing towards the new position of each
7974 # wheel divided by the radius of the turning circle.
8075 vectorDistanceWithoutR <- 2 * sin(theta / 2 )
81-
82- # If inverted, swap which wheel gets which input
83- if (inverted ){
84- out [i , 2 ] <- out [i - 1 ,2 ]+ vectorDistanceWithoutR * rightR * cos(vectorTheta )
85- out [i , 3 ] <- out [i - 1 ,3 ]+ vectorDistanceWithoutR * rightR * sin(vectorTheta )
86- out [i , 4 ] <- out [i - 1 ,4 ]+ vectorDistanceWithoutR * leftR * cos(vectorTheta )
87- out [i , 5 ] <- out [i - 1 ,5 ]+ vectorDistanceWithoutR * leftR * sin(vectorTheta )
88- } else {
89- out [i , 2 ] <- out [i - 1 ,2 ]+ vectorDistanceWithoutR * leftR * cos(vectorTheta )
90- out [i , 3 ] <- out [i - 1 ,3 ]+ vectorDistanceWithoutR * leftR * sin(vectorTheta )
91- out [i , 4 ] <- out [i - 1 ,4 ]+ vectorDistanceWithoutR * rightR * cos(vectorTheta )
92- out [i , 5 ] <- out [i - 1 ,5 ]+ vectorDistanceWithoutR * rightR * sin(vectorTheta )
93- }
76+
77+ out [i , 2 ] <- out [i - 1 ,2 ]+ vectorDistanceWithoutR * leftR * cos(vectorTheta )
78+ out [i , 3 ] <- out [i - 1 ,3 ]+ vectorDistanceWithoutR * leftR * sin(vectorTheta )
79+ out [i , 4 ] <- out [i - 1 ,4 ]+ vectorDistanceWithoutR * rightR * cos(vectorTheta )
80+ out [i , 5 ] <- out [i - 1 ,5 ]+ vectorDistanceWithoutR * rightR * sin(vectorTheta )
9481 }
9582 }
9683 return (out )
@@ -100,9 +87,9 @@ drawProfile <- function (coords, centerToFront, centerToBack, wheelbaseDiameter,
10087
10188 if (clear ){
10289 if (linePlot ){
103- plot(coords [,2 ],coords [,3 ], type = " l" , col = " Green" , ylim = c(- 16 , 16 ),xlim = c(0 ,54 ), asp = 1 )
90+ plot(coords [,2 ],coords [,3 ], type = " l" , col = " Green" , ylim = c(- 16 , 16 ),xlim = c(0 ,54 ), xlab = " X Position (feet) " , ylab = " Y Position (feet) " , asp = 1 )
10491 } else {
105- plot(coords [,2 ],coords [,3 ], col = " Green" , ylim = c(- 16 , 16 ), xlim = c(0 ,54 ), asp = 1 )
92+ plot(coords [,2 ],coords [,3 ], col = " Green" , ylim = c(- 16 , 16 ), xlim = c(0 ,54 ), xlab = " X Position (feet) " , ylab = " Y Position (feet) " , asp = 1 )
10693 }
10794 field <- read.csv(" field.csv" )
10895 # Strings are read as factors by default, so we need to do this to make it read them as strings
@@ -124,38 +111,9 @@ drawProfile <- function (coords, centerToFront, centerToBack, wheelbaseDiameter,
124111 }
125112}
126113
127- angleBetween <- function (leftX , leftY , rightX , rightY ){
128- deltaX <- leftX - rightX
129- deltaY <- leftY - rightY
130- if (identical(deltaX , 0 )){
131- ans <- pi / 2
132- } else {
133- # Pretend it's first quadrant because we manually determine quadrants
134- ans <- atan(abs(deltaY / deltaX ))
135- }
136- if (deltaY > 0 ){
137- if (deltaX > 0 ){
138- # If it's actually quadrant 1
139- return (ans )
140- }else {
141- # quadrant 2
142- return (pi - ans )
143- }
144- return (ans )
145- } else {
146- if (deltaX > 0 ){
147- # quadrant 4
148- return (- ans )
149- }else {
150- # quadrant 3
151- return (- (pi - ans ))
152- }
153- }
154- }
155-
156114drawRobot <- function (robotFile , robotPos ){
157- theta <- angleBetween( leftX = robotPos [2 ], leftY = robotPos [3 ], rightX = robotPos [4 ], rightY = robotPos [5 ])
158- perp <- theta - pi / 2
115+ theta <- atan2( robotPos [5 ] - robotPos [3 ], robotPos [4 ] - robotPos [2 ])
116+ perp <- theta + pi / 2
159117 robotCenter <- c((robotPos [2 ]+ robotPos [4 ])/ 2 . ,(robotPos [3 ]+ robotPos [5 ])/ 2 . )
160118 robot <- read.csv(robotFile )
161119 rotMatrix <- matrix (c(cos(perp ), - sin(perp ), sin(perp ), cos(perp )), nrow = 2 , ncol = 2 , byrow = TRUE )
@@ -177,16 +135,16 @@ wheelbaseDiameter <- 26./12.
177135centerToFront <- (27 . / 2 . )/ 12 .
178136centerToBack <- (27 . / 2 . + 3.25 )/ 12 .
179137centerToSide <- (29 . / 2 . + 3.25 )/ 12 .
180-
181- out <- plotProfile(profileName = " BlueRight " , inverted = FALSE , wheelbaseDiameter = wheelbaseDiameter , centerToFront = centerToFront ,centerToBack = centerToBack ,centerToSide = centerToSide , startY = - 10.3449 + centerToSide , usePosition = TRUE )
138+ # Time, Left X, Left Y, Right X, Right Y
139+ out <- plotProfile(profileName = " RedRight " , inverted = FALSE , wheelbaseDiameter = wheelbaseDiameter , centerToFront = centerToFront ,centerToBack = centerToBack ,centerToSide = centerToSide , startPos = c( 0 , 54 - centerToBack , 10.3449 - wheelbaseDiameter , 54 - centerToBack , 10.3449 , pi ) , usePosition = TRUE )
182140drawProfile(coords = out , centerToFront = centerToFront , centerToBack = centerToBack , wheelbaseDiameter = wheelbaseDiameter , clear = TRUE , linePlot = TRUE )
183141tmp <- out [length(out [,1 ]),]
184142drawRobot(" robot.csv" , tmp )
185- out2 <- plotProfile(profileName = " BlueBackup " ,inverted = TRUE ,wheelbaseDiameter = wheelbaseDiameter ,centerToFront = centerToFront ,centerToBack = centerToBack ,centerToSide = centerToSide ,startPos = tmp )
143+ out2 <- plotProfile(profileName = " RedBackup " ,inverted = TRUE ,wheelbaseDiameter = wheelbaseDiameter ,centerToFront = centerToFront ,centerToBack = centerToBack ,centerToSide = centerToSide ,startPos = tmp )
186144drawProfile(coords = out2 , centerToFront = centerToFront , centerToBack = centerToBack , wheelbaseDiameter = wheelbaseDiameter , clear = FALSE )
187145tmp2 <- out2 [length(out2 [,1 ]),]
188146drawRobot(" robot.csv" , out2 [length(out2 [,1 ]),])
189- out3 <- plotProfile(profileName = " BlueLoadingToLoading " ,inverted = FALSE ,wheelbaseDiameter = wheelbaseDiameter ,centerToFront = centerToFront ,centerToBack = centerToBack ,centerToSide = centerToSide ,startPos = tmp2 )
147+ out3 <- plotProfile(profileName = " RedBoilerToLoading " ,inverted = FALSE ,wheelbaseDiameter = wheelbaseDiameter ,centerToFront = centerToFront ,centerToBack = centerToBack ,centerToSide = centerToSide ,startPos = tmp2 )
190148drawProfile(coords = out3 , centerToFront = centerToFront , centerToBack = centerToBack , wheelbaseDiameter = wheelbaseDiameter , clear = FALSE )
191149drawRobot(" robot.csv" , out3 [length(out3 [,1 ]),])
192150
0 commit comments