Designing a simple electric vehicle in Collimator

Designing a simple electric vehicle in CollimatorDesigning a simple electric vehicle in Collimator

Electric vehicles are vehicles that utilize electric motors for traction. The source of electricity can be a solar cell, a fuel cell, or a battery. Electric vehicles have gained popularity due to their reduced carbon emissions. More sophisticated and flexible design tools are in great demand to keep up with the industry requirements for building competitive electric vehicles. In this tutorial, we will learn how to build and simulate an electric vehicle in Collimator. We will use an electric vehicle model designed by Emran, 2020 at Clemson University International Center for Automotive Research.

The electric vehicle model consists of the the following subsystems:

  1. The longitudinal dynamics model which contains the equations of motion for the longitudinal motion
  2. Powertrain model comprising the electric motors model and the drivetrain
  3. Tire forces model
  4. Battery
  5. Human driver model

First, we will start by importing some useful libraries:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors
import control as ctrl
import collimator as C

Longitudinal dynamics model

The total force leading to longitudinal motion is the result of the result of the following forces affecting the vehicle. The figure below shows the forces acting on the longitudinal vehicle dynamics.

Diagram of forces acting on a vehicle

1. Traction Force \(F_T\) : The force that is responsible for generating motion through dry friction between the tires and the road surface.

$$F_T = F_{T,f}+F_{T,r}$$

2. Rolling Force \(F_R\) : The force resisting the motion that is generated by the tires

$$F_{R,i} = C_RF_{N,i}$$

where \(C_R=0.009\) is the rolling coefficient, \(F_N\) is the normal or reactive tire force, and  \(i\in\{f,r\}\).

3. Drag Force \(F_D\) : The force generated by the wind that slows the car down.

$$F_D = \frac{1}{2}\rho A C_D v^2$$

where \(\rho=1.26\ kg/m^3\), \(A=2.5844\ m^2\) is the vehicle frontal area, \(C_D=0.27\) is the drag coefficient factor, and \(v\) is the vehicle longitudinal velocity.

4. The weight force \(F_W\) : This is the vehicle weight projected on the longitudinal axis.

$$F_W = mg\text{sin}\left(\theta\right)$$

where \(m=1540\ kg\) is the vehicle mass, \(g = 9.81\ m/s^2\) is the gravitational acceleration, and \(\theta\) is the road slope angle.

The total longitudinal force is the summation of the affecting forces as:

$$ma=F_T+F_R+F_D+F_W$$

where \(a\) is the vehicle longitudinal acceleration.

The longitudinal dynamics can be modelled in Collimator's Model Editor as the following diagram:

Longitudinal dynamics applied on a car

Powertrain model

The powertrain is made up of the vehicle’s assembly and is responsible for generating a traction force. The powertrain in electric vehicles consists of an electric motor and a drivetrain. The drivetrain transmits the power from the electric motor to the wheels. In a rear wheel drive configuration, the motor power is transmitted via a driveline shaft to the rear wheels.

Diagram of the powertrain

Electric Motor Model

For this model, we will use a curve-fitted function based on measured data points to model the speed-torque curve. In addition, we will model the electric motor efficiency map as a lookup table to capture it's nonlinearity. Here, we will plot the maximum torque curve alongside the nonlinear efficiency map. The maximum torque-speed function is defined as:

$$ T_{max} =  \left\{\begin{array}{} 765 & \omega_{motor}<326.3766 \\ -3.11 \hat{\omega}_{motor}^3 + 18.64 \hat{\omega}_{motor}^2 - 98.65 \hat{\omega}_{motor} + 553.16& \omega_{motor}\geq326.3766 \\ \end{array} \right.$$

where \(\hat{\omega}_{motor}\) is a scaled and centered version of \(\omega_{motor}\) :

$$\hat{\omega}_{motor} = \frac{\omega_{motor}-\bar{\omega}_{motor}}{\sigma}$$

The scaled motor speed improves numbers conditioning for the curve-fitted equation. For the motor speed data points, the mean is \(\bar{\omega}_{motor}=451.2\) and the standard deviation is \(\sigma=80.31\).  

The output motor torque is determined by:

$$T = U_aT_{max}$$

where \(0\leq U_a \leq 1\) is the acceleration pedal command percentage.

The max torque-speed function is coded in a Python script as follows:

def speed_2_torque(motor_speed):
    # Define Constants
    constant_torque = 765
    base_speed = 326.3766
    p1 = -3.113768123110436
    p2 = 18.640436529262388
    p3 = -98.651411733382490
    p4 = 553.1557411341237
    mu = 451.2
    sig = 80.31
    
    if motor_speed <= base_speed:
        motor_torque = constant_torque
    else:
        motor_speed_n = (motor_speed-mu)/sig
        motor_torque = p1*motor_speed_n**3 + p2*motor_speed_n**2 + p3*motor_speed_n + p4
        
    if motor_speed >= 576:
        motor_torque = 0
    return motor_torque

Then, we have a look at our motor-inverter efficiency map. The efficiency map is a nonlinear function that is modelled through a look-up table. First, we load the look-up table data:

motor_speed = np.genfromtxt('motor_speed.csv', delimiter=',')
motor_torque = np.genfromtxt('motor_torque.csv', delimiter=',')
motor_eff_map = np.genfromtxt('motor_eff_map.csv', delimiter=',')

Here, we plot the contour lines of the motor efficiency map within the maximum torque curve:

Omega, Torque = np.meshgrid(motor_speed, motor_torque)
# Generate max torque curve
Omega_Max = np.arange(0,577,1)
vf = np.vectorize(speed_2_torque)
Torque_Max = vf(Omega_Max)
# clean contour lines outside the max torque curve
for i in range(motor_torque.size):
    for j in range(motor_speed.size):
        if  Torque[i][j] > speed_2_torque(Omega[i][j]):
            motor_eff_map[i][j] = np.nan

fig = plt.figure(figsize=(12,6))
ax = plt.axes()
ax.set_title('Motor Torque Curve and Efficiency Map')
ax.set_xlabel('Motor speed (rad/s)')
ax.set_ylabel('Motor torque (N.m)')
ax.set_xlim(right=600)
ax.set_ylim(top = 800)
# Plot contour lines of motor efficiency 
my_levels = np.append(np.arange(0.5,0.9,0.05),np.arange(0.9,1,0.005))
c = plt.contour(Omega,Torque, motor_eff_map, levels = my_levels, cmap='Spectral')
ax.clabel(c, inline=1, fontsize=10) # label contour lines
# Plot continuous colorbar
norm= matplotlib.colors.Normalize(vmin=c.cvalues.min(), vmax=c.cvalues.max())
sm = plt.cm.ScalarMappable(norm=norm, cmap = c.cmap)
sm.set_array([])
fig.colorbar(sm,ax=ax)
# Plot max torque curve
plt.plot(Omega_Max,Torque_Max,linewidth=3,color='k')
plt.show()

The contour lines of the motor efficiency map

The above combination of the maximum torque curve with the motor efficiency map can be modelled in Collimator's Model Editor as the figure below representing the electric motor submodel:

The electric motor submodel

Drivetrain Model

Now, we can build the drivetrain model. The relation between the vehicle velocity and the motor speed is linear and depends on tire radius and the final drive ratio.

$$ \omega_{motor} = \frac{N_{final\ drive}}{r_{tire}}v $$

where \(N_{final\ drive}=2\) is the final drive ratio, and \(r_{tire}=0.32985m\) is the tire radius.

We assume that our vehicle has a rear wheel drive configuration with two electric motors. Therefore, we define the traction forces for the rear wheels as:

$$F_{T,r}=\frac{\eta N_{final\ drive} N_{motors}}{r_{tire}}T+BU_{b}$$

where \(\eta=90\%\) is the drivetrain efficiency, \(N_{motors}=2\) is the number of motors connected on the rear-axle, \(B=10^4\) is the braking gain, and \(-1\leq U_{b}\leq0\) is the braking pedal command percentage.

On the other hand, the forward wheels are not affected by motor torque and the only force there is the braking force:

$$ F_{T,f}=BU_{b}$$

In order for the dynamical model to make physical sense, the traction force is constrained by the maximum friction generated due to reactive forces:

$$|F_{T,i}| \leq \mu F_{N,i} $$

where \(\mu=0.9\) is the assumed friction factor for a dry asphalt road, and \(i\in\{f,r\}\).  

The drivetrain submodel is implemented in Collimator's Model Editor as the figure below.

Drivetrain Submodel

Tire forces model

In this model, we will consider only the longitudinal forces that produce the normal forces acting on the vehicle body. These normal forces are called reactive forces which are the opposing forces pushing toward the vehicle's weight.

The reactive forces equations is extracted using angular momentum conservation law at each contact point. The forward reactive force can be calculated by investigating the angular momentum at the rear contact point:

$$L_{101}F_{N,f}= m g\text{cos}\left(\theta\right) {CG}_r - m a {CG}_h - mg\text{sin}\left(\theta\right){CG}_h$$

Similarly, the rear reactive force can be calculated at the forward contact point as:

$$L_{101}F_{N,r}= m g\text{cos}\left(\theta\right) {CG}_f + m a {CG}_h + mg\text{sin}\left(\theta\right){CG}_h$$

where \(L_{101} = 2.7\ m\) is the wheel base length, \({CG}_h = 0.4\ m\) is the height of the center of gravity, \({CG}_f = 1.4\ m\) and \({CG}_r = 1.3\ m\) are the horizontal distances from thecenter of gravity to forward and rear wheels centers, respectively.  

The tire forces submodel can be implemented as the figure below.

The submodel of the forces acting on the tires

EV battery model

The battery is modelled as a simple first-order system. We will assume that our electric vehicle will have a battery capacity within the average ranges of \(40\ kWh\). The energy consumption is described by the following differential equation:

$$\frac{dE}{dt} = -\frac{1}{\eta_m}N_{motor}\omega_{motor} T$$

where \(\eta_m\) is the motor efficiency, \(N_{motor}=2\) is the number of motors connected to the rear axle, \(\omega_{motor}\) is the motor speed, and \(T\) is the motor torque.

We assume that the battery has a usability ratio of \(95\%\). Subsequently, the usable battery capacity in SI units is calculated as:

$$Q_u = 40 \times 1000 \times 3600 \times 0.95 = 136800000\ Ws$$

The battery subsystem is modelled in Collimator as follows.

Battery submodel

Drive cycle

To evaluate the performance of the electric vehicle, we will apply a drive cycle to the model. A drive cycle is just a pre-recorded velocity profile for a real drive scenario. We will apply a segment of a US06 drive cycle from NREL_DriveCAT. The US06 drive cycle is described as:

High speed, high acceleration, aggressive driving schedule designed to measure off-cycle emissions. Also known as the Environmental Protection Agency (EPA) Supplemental Federal Test Procedure (FTP) Driving Schedule.

Lets take a look at the segment we will apply for our simulation:

us06 = np.genfromtxt('US06_DrivingSchedule_LightDuty_Segment.csv',delimiter=',',skip_header=1)
fig = plt.figure(figsize=(12,6))
ax = plt.axes()
ax.set_title('A Segment of US06 Drive Cycle')
ax.set_xlabel('Time (s)')
ax.set_ylabel('Velocity (km/h)')
ax.set_ylim(bottom = 0,top = 100)
ax.set_xlim(left = 0,right = 360)
plt.plot(us06[:,0].T,us06[:,1].T)
plt.grid(True)
plt.show()

US06 drive cycle

We will model the human driver behavior as a simple PI controller:

$$C\left(s\right) = 0.5+\frac{0.03}{s}$$

For the transfer function above, the positive output actions are interpreted as the acceleration pedal commands while the negative output actions are interpreted as the braking pedal commands. The driver model is implemented as the following submodel:

Submodel of a real driver

Electric vehicle results

The dataset for the drive cycle is included in the ‚ÄėUS06_Segment.csv‚Äô file, we will use a Data Source block to read the data in the Collimator Model Editor. The complete model is shown in the following figure:

Complete electric vehicle model

The final simulation results for the US06 drive cycle are shown below:

US06 drive cycle model simulation results
Try it in Collimator

What our customers are saying