Calculate variables using equations then use the g

2019-08-19 11:51发布

It's hard to explain it but i'll take it step by step

Let's say I've 2 cars, one following another, and I've the speed of the lead car, and I want to calculate the distance between two of them, and we can calculate the distance using multiple equations, also I know the initial speed of the following car and the distance between two of them.

Following_Car_Speed = 13.68490 m/s
Distance = 17.024 m
Lead_Car_Speed = c(13.784896, 13.745834, 13.880556, 13.893577, 13.893577, 13.923959, 
13.945661, 13.919619, 13.897917, 14.002257, 14.002257, 13.980556, 
13.980556, 14.067536, 14.063195, 14.080556, 14.123959, 14.163021, 
14.236806, 14.167188)

Delta_Speed = Lead_Car_Speed[1]-Following_Car_Speed = 13.784896-13.68490 = 0.1

Gap <- 1.554 +  Following_Car_Speed*0.878- (Following_Car_Speed*Delta_Speed)/(2*sqrt(0.8418*0.8150))=
   1.554+ 13.68490*0.878- (13.68490*0.1)/(2*sqrt(0.8418*0.8150) = 12.74325
Acceleration <- 0.8418*(1-(Following_Car_Speed/29.2)^3.52-(Gap/Distance)^2)=0.3116923

Now I've calculated the acceleration, so I've to calculate the new speed of the following car .

Following_Car_Speed <- Following_Car_Speed + Acceleration*0.1 

So now I've to calculate the new delta in speed between the lead and following car

Delta_Speed <- Lead_Car_Speed[2]-Following_Car_Speed
Distance<- Distance+(Delta_Speed[2]+Delta_Speed[1])/2*0.1

Then continue using the same equations till we end all the values of the following car.

It's easy to do this using For loops, but i want to get a more efficient way, I tried to use dplyr, but it's hard and I failed to get an answer.

So please help me.


myfun <- function(list, lcs,lcs2){
        ds <- lcs - list[[1]]
        Distance <- list[[1]]*D_Time - (list[[1]] * ds) / (2*sqrt(M_Acc*Com_Acc))
        if (Distance < 0|is.na(Distance)) {Distance <- 0}
        gap <-  Gap_J + Distance
        acc <- M_Acc * (1 - (list[[1]] / D_Speed)^Beta - (gap / list[[2]])^2)
        fcs_new <- list[[1]] + acc * 0.1
        ds_new <- lcs2- fcs_new
        di_new <- list[[2]]+(ds_new+ds)/2*0.1
        return(list(Speed = fcs_new,Distance = di_new))

} 

Generated_Data <- data %>%group_by(Driver,FileName)%>%
        mutate(Speed_Distance_Calibrated = accumulate2( .init = list(Filling_Speed[1],
                                                                     Filling_Range[1]),.x =  Lead_Veh_Speed_F,.y = Lead_Veh_Speed_F2, myfun)[-1])%>%ungroup()

I've add the lead of the lead_car_speed also i wanted to use the new distance and new speed, so i made it into a list and put it into .initla

2条回答
Viruses.
2楼-- · 2019-08-19 12:08

Your operation depends on the iteration or some sort of recursion to be complete (due to possible NA, Inf etc) - seems like for or while is needed.

My alternative version is to break down the functions into easier unit for scaling and unit test for larger example or wrap around with another function calls .

I assume your var Distance is fixed for some reason and expected output is not provided, so I can't verify the functions completely.

Following_Car_Speed <- 13.68490
Lead_Car_Speed <- c(13.784896, 13.745834, 13.880556, 13.893577, 13.893577, 
                    13.923959, 13.945661, 13.919619, 13.897917, 14.002257, 
                    14.002257, 13.980556, 13.980556, 14.067536, 14.063195, 
                    14.080556, 14.123959, 14.163021, 14.236806, 14.167188)
Distance <- 17.024

#init
i <- length(Lead_Car_Speed)
Delta_Speed <- c(0.1, vector(mode = "numeric", length = i-1))
Gap <- c(12.74325, vector(mode = "numeric", length = i-1))
Acceleration <- c(0.3116923, vector(mode = "numeric", length = i-1 ))
Following_Car_Speed <- c(Following_Car_Speed, vector(mode="numeric", length = i-1 ))

cal.following.car.speed <- function(Following_Car_Speed, Acceleration){

  #calculate and return current following-car-speed: the i-th following-car-speed
  current.follow.car.speed <- Following_Car_Speed + Acceleration*0.1

  return(current.follow.car.speed)
}                                    

cal.delta.speed <- function(Lead_Car_Speed, following.car.speed){

  #calculate and return current delta speed: the i-th delta speed
  current.delta.speed <- Lead_Car_Speed - following.car.speed

  return(current.delta.speed)
}

cal.gap <- function(Following_Car_Speed, Delta_Speed){

  #calculate and return current gap: the i-th gap
  current.gap <- 1.554 + Following_Car_Speed*0.878 - (Following_Car_Speed*Delta_Speed)/(2*sqrt(0.8418*0.8150))

  return(current.gap)
}

cal.acceleration <- function(Following_Car_Speed, Gap, Distance){

  #calculate and return current acceleration: the i-th acceleration
  current.acceleration <- 0.8418*(1-(Following_Car_Speed/29.2)^3.52-(Gap/Distance)^2)

  return(current.acceleration)
}

#main
counter <- 1

while(counter != i){

  if(counter == 1) {counter = counter + 1} #skip 1st ith as we have init
  else{

    Gap[counter] <- cal.gap(Following_Car_Speed[counter-1], Delta_Speed[counter-1])  

    Acceleration[counter] <- cal.acceleration(Following_Car_Speed[counter-1], Gap[counter-1], Distance)

    Following_Car_Speed[counter] <- cal.following.car.speed(Following_Car_Speed[counter-1], Acceleration[counter])

    Delta_Speed[counter] <- cal.delta.speed(Lead_Car_Speed[counter], Following_Car_Speed[counter])

    counter = counter + 1
  }
}

cbind(Delta_Speed, Gap, Acceleration, Following_Car_Speed)
查看更多
成全新的幸福
3楼-- · 2019-08-19 12:13

Here is a simple way using accumulate from the purrr package which is part of the tidyverse.

First I define a function myfun which updates the following_car_speed (fcs).

myfun <- function(fcs, lcs, di){
  ds <- lcs - fcs
  gap <-  1.554 + fcs*0.878 - fcs * ds / (2*sqrt(0.8418*0.8150))
  acc <- 0.8418 * (1 - (fcs / 29.2)^3.52 - (gap / di)^2)
  fcs_new <- fcs + acc * 0.1

  return(fcs_new)
} 

library(tidyverse)

tibble(lead_car_speed = c(13.784896, 13.745834, 13.880556, 13.893577, 13.893577, 13.923959, 
                          13.945661, 13.919619, 13.897917, 14.002257, 14.002257, 13.980556, 
                          13.980556, 14.067536, 14.063195, 14.080556, 14.123959, 14.163021, 
                          14.236806, 14.167188)) %>%
  mutate(following_car_speed = accumulate(lead_car_speed, myfun, .init = 13.68490, di = 17.024)[-1])^


# A tibble: 20 x 2
   lead_car_speed   following_car_speed
            <dbl> <dbl>
 1           13.8  13.7
 2           13.7  13.7
 3           13.9  13.8
 4           13.9  13.8
 5           13.9  13.8
 6           13.9  13.9
 7           13.9  13.9
 8           13.9  13.9
 9           13.9  13.9
10           14.0  14.0
11           14.0  14.0
12           14.0  14.0
13           14.0  14.0
14           14.1  14.1
15           14.1  14.1
16           14.1  14.1
17           14.1  14.1
18           14.2  14.1
19           14.2  14.2
20           14.2  14.2

If distance changes as well you can use accumulate2 rather than accumulate.

查看更多
登录 后发表回答