使用方程式计算变量,然后使用生成的值生成新的值

Calculate variables using equations then use the generated values to generate new one

很难解释,但我会一步一步来

假设我有 2 辆车,一前一后,我知道前车的速度,我想计算两辆车之间的距离,我们可以使用多个方程式计算距离,我也知道后车的初速和两车之间的距离

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

现在我已经计算了加速度,所以我要计算后面的车的新速度。

Following_Car_Speed <- Following_Car_Speed + Acceleration*0.1 

所以现在我要计算前车和后车之间的新速度差值

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

然后继续使用相同的方程式,直到我们结束以下汽车的所有值。

使用 For 循环很容易做到这一点,但我想获得更有效的方法,我尝试使用 dplyr,但很难,我没有得到答案。

所以请帮助我。


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()

我已经添加了 lead_car_speed 的领先优势,我也想使用新的距离和新的速度,所以我将它放入列表并放入 .initla

您的操作取决于迭代或某种递归来完成(由于可能 NAInf 等)- 看起来像 forwhile需要。

我的替代版本是将函数分解为更简单的单元,以便对更大的示例进行缩放和单元测试,或者用另一个函数调用环绕。

我假设您的 var Distance 由于某种原因已修复并且未提供预期的输出,因此我无法完全验证函数。

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)

这是使用 purrr 包中的 accumulate 的简单方法,它是 tidyverse 的一部分。

首先我定义了一个函数 myfun 来更新 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

如果距离也发生变化,您可以使用 accumulate2 而不是 accumulate