carla-simulator / carla

Open-source simulator for autonomous driving research.
http://carla.org
MIT License
10.79k stars 3.47k forks source link

Electric cars (Tesla Model 3): vehicle dynamics seem inaccurate #3256

Open hh0rva1h opened 3 years ago

hh0rva1h commented 3 years ago

Actual behavior

In the following code we spawn a Tesla Model 3, accelerate it until approx 20 m/s, then we try to hold that speed and afterwards we set throttle to zero.

aimport carla
from math import sqrt

# initialise carla with our default map
client = carla.Client("localhost", 2000)
client.set_timeout(5)
world = client.load_world("Town06")

settings = world.get_settings()
settings.fixed_delta_seconds = 0.045
settings.synchronous_mode = True
settings.no_rendering_mode = True
world.apply_settings(settings)
blueprints = world.get_blueprint_library()

print(world.get_map().get_spawn_points()[1])

# spawn our favourite car
default_car = blueprints.find("vehicle.tesla.model3")
#position = carla.Transform(carla.Location(x=350, y=12.5, z=3), carla.Rotation(yaw=180))
position = carla.Transform(carla.Location(x=626.831238, y=-13.563108, z=0.300000), carla.Rotation(yaw=180))
vehicle = world.spawn_actor(default_car, position)

for i in range(20):
    try:
        world.tick()
    except:
        print("Skipped tick")

weather = carla.WeatherParameters(
    cloudiness=80.0,
    precipitation=30.0,
    sun_altitude_angle=70.0)

world.set_weather(weather)

# workaround unrealistic Carla phenomenas
#physics_control = vehicle.get_physics_control()
#physics_control.gear_switch_time=0.01
#physics_control.damping_rate_zero_throttle_clutch_engaged=physics_control.damping_rate_zero_throttle_clutch_disengaged
#vehicle.apply_physics_control(physics_control)
#vehicle.apply_control(carla.VehicleControl(throttle=0, brake=1, manual_gear_shift=True, gear=1))
#for i in range(9):
#    try:
#        world.tick()
#    except:
#        print("Skipped tick")

world.get_spectator().set_transform(position)

#exit()

# full throttle in the beginning
vehicle.apply_control(carla.VehicleControl(throttle=1.0))
print("Full throttle")
for _ in range(20):
    try:
        world.tick()
    except:
        print("Skipped tick")

# use norm of velocity and accel vectors (maybe try to disregard z?)
def norm(vector):
    return sqrt(vector.x**2 + vector.y**2 + vector.z**2)

# log all vehicle data in lists
accel_log = []
velocity_log = []
throttle_log = []
brake_log = []
z_log = []

# accelerate up to 20m/s and then apply throttle=0.82 to stay there until set location
throttle_changed = False
throttle = 1.0
while vehicle.get_location().x > 0:
    try:
        world.tick()
    except:
        print("Skipped tick")
    a = vehicle.get_acceleration()
    a_x = 0 if a.x == 0 else -norm(a)*a.x/abs(a.x)

    v = vehicle.get_velocity()
    v_x = 0 if v.x == 0 else -norm(v)*v.x/abs(v.x)
    if not throttle_changed and v_x > 20: # 20 40
        throttle = 0.82 # 0.48 0.77
        print(f"Apply throttle={throttle} and hold speed")
        throttle_changed = True

    vehicle.apply_control(carla.VehicleControl(throttle=throttle))

    accel_log.append(a_x)
    print(a_x)
    velocity_log.append(v_x)
    throttle_log.append(throttle)
    brake_log.append(0.0)
    z_log.append(a.z)

# now change throttle and brake to see the impact on the velocity
throttle = 0.0
brake = 0.0

print(f"Apply throttle={throttle}, brake={brake}")
vehicle.apply_control(carla.VehicleControl(throttle=throttle, brake=brake))

# break the loop at some coordinate or when the velocity is low enough
while vehicle.get_location().x > -300:
    try:
        world.tick()
    except:
        print("Skipped tick")
    a = vehicle.get_acceleration()
    a_x = 0 if a.x == 0 else -norm(a)*a.x/abs(a.x)

    v = vehicle.get_velocity()
    v_x = 0 if v.x == 0 else -norm(v)*v.x/abs(v.x)
    if v_x < 2:
        print("Vehicle stopped")
        break

    accel_log.append(a_x)
    throttle_log.append(throttle)
    brake_log.append(brake)
    velocity_log.append(v_x)
    z_log.append(a.z)
else:
    print("Vehicle has driven outside the test area")

import matplotlib.pyplot as plt

# first plot the velocities, accels, throttle and brake values by tick number (implicit indexing)
plt.plot(velocity_log, label="v")
plt.plot(accel_log, label="a")
plt.plot(z_log, label="z cooridnate")
# throttle and brake are scaled *10 to make them readable
plt.plot([10*t for t in throttle_log], label="throttle*10")
plt.plot([10*b for b in brake_log], label="brake*10")
plt.legend()

plt.show()

The plot looks as follows: Screenshot from 2020-09-03 00-58-32

Expected behavior

Looking at the plot there are two issues for us:

  1. the acceleration values in the beginning are really crazy high, this is physically impossible with a real car
  2. the deceleration of the vehicle when setting throttle to zero is also quite high, we know that the Tesla Model 3 has a regenerative breaks which comes to play when not giving throttle, however according to our research it should be anywhere that extreme (we found a maximum of 0.2g of deceleration reported by tesla), furthermore the regenerative brake can be configured for electric vehicles.

Rootcause and workaround

We found out that the spike in the beginning is due to the gear switch that Carla is doing: It goes from gear 0 to gear 1 with a preconfigured gear shift time. This just feels wrong to us. An electric car is not doing any gear switch and thus the simulation of a gear shift here is clearly unrealistic.

Therefore we came up with the following workaround to make the vehicle dynamics saner:

# reduce gear switch time
physics_control = vehicle.get_physics_control()
physics_control.gear_switch_time=0.01
# since we have an electric care make sure we do not have a clutch related damping rate
physics_control.damping_rate_zero_throttle_clutch_engaged=physics_control.damping_rate_zero_throttle_clutch_disengaged
# make sure we set gear 1 before applying throttle
vehicle.apply_physics_control(physics_control)
# wait for the gear switch to be complete
vehicle.apply_control(carla.VehicleControl(throttle=0, brake=1, manual_gear_shift=True, gear=1))
for i in range(4):
    world.tick()

This changes the vehicle dynamics of course, so the throttle value to hold the speed as before is now around 0.475 as compared to 0.82 before. However the vehicle dynamics looks a lot saner to us now (the deceleration is a little over 0.2g which seems ok): The acceleration behavior in the beginning is still not perfect as you can see, but it's a lot saner. It would be nice if there were no clutch effect at all for eletric cars.

Screenshot from 2020-09-03 01-16-16

For easier reproducibility the full code of the plot above:

import carla
from math import sqrt

# initialise carla with our default map
client = carla.Client("localhost", 2000)
client.set_timeout(5)
world = client.load_world("Town06")

settings = world.get_settings()
settings.fixed_delta_seconds = 0.02
settings.synchronous_mode = True
settings.no_rendering_mode = True
world.apply_settings(settings)
blueprints = world.get_blueprint_library()

print(world.get_map().get_spawn_points()[1])

# spawn our favourite car
default_car = blueprints.find("vehicle.tesla.model3")
#position = carla.Transform(carla.Location(x=350, y=12.5, z=3), carla.Rotation(yaw=180))
position = carla.Transform(carla.Location(x=626.831238, y=-13.563108, z=0.300000), carla.Rotation(yaw=180))
vehicle = world.spawn_actor(default_car, position)

for i in range(20):
    try:
        world.tick()
    except:
        print("Skipped tick")

weather = carla.WeatherParameters(
    cloudiness=80.0,
    precipitation=30.0,
    sun_altitude_angle=70.0)

world.set_weather(weather)

# workaround unrealistic Carla phenomenas
physics_control = vehicle.get_physics_control()
physics_control.gear_switch_time=0.01
physics_control.damping_rate_zero_throttle_clutch_engaged=physics_control.damping_rate_zero_throttle_clutch_disengaged
vehicle.apply_physics_control(physics_control)
vehicle.apply_control(carla.VehicleControl(throttle=0, brake=1, manual_gear_shift=True, gear=1))
for i in range(9):
    world.tick()

world.get_spectator().set_transform(position)

#exit()

# full throttle in the beginning
vehicle.apply_control(carla.VehicleControl(throttle=1.0))
print("Full throttle")
for _ in range(20):
    try:
        world.tick()
    except:
        print("Skipped tick")

# use norm of velocity and accel vectors (maybe try to disregard z?)
def norm(vector):
    return sqrt(vector.x**2 + vector.y**2 + vector.z**2)

# log all vehicle data in lists
accel_log = []
velocity_log = []
throttle_log = []
brake_log = []
z_log = []

# accelerate up to 20m/s and then apply throttle=0.82 to stay there until set location
throttle_changed = False
throttle = 1.0
while vehicle.get_location().x > 0:
    try:
        world.tick()
    except:
        print("Skipped tick")
    a = vehicle.get_acceleration()
    a_x = 0 if a.x == 0 else -norm(a)*a.x/abs(a.x)

    v = vehicle.get_velocity()
    v_x = 0 if v.x == 0 else -norm(v)*v.x/abs(v.x)
    if not throttle_changed and v_x > 20: # 20 40
        throttle = 0.475 # 0.48 0.77
        print(f"Apply throttle={throttle} and hold speed")
        throttle_changed = True

    vehicle.apply_control(carla.VehicleControl(throttle=throttle))

    accel_log.append(a_x)
    print(a_x)
    velocity_log.append(v_x)
    throttle_log.append(throttle)
    brake_log.append(0.0)
    z_log.append(a.z)

# now change throttle and brake to see the impact on the velocity
throttle = 0.0
brake = 0.0

print(f"Apply throttle={throttle}, brake={brake}")
vehicle.apply_control(carla.VehicleControl(throttle=throttle, brake=brake))

# break the loop at some coordinate or when the velocity is low enough
while vehicle.get_location().x > -300:
    try:
        world.tick()
    except:
        print("Skipped tick")
    a = vehicle.get_acceleration()
    a_x = 0 if a.x == 0 else -norm(a)*a.x/abs(a.x)

    v = vehicle.get_velocity()
    v_x = 0 if v.x == 0 else -norm(v)*v.x/abs(v.x)
    if v_x < 2:
        print("Vehicle stopped")
        break

    accel_log.append(a_x)
    throttle_log.append(throttle)
    brake_log.append(brake)
    velocity_log.append(v_x)
    z_log.append(a.z)
else:
    print("Vehicle has driven outside the test area")

import matplotlib.pyplot as plt
#fig, (ax1, ax2, ax3) = plt.subplots(nrows=3, sharex=True)  # add ax4 in a new row for log scale

# first plot the velocities, accels, throttle and brake values by tick number (implicit indexing)
plt.plot(velocity_log, label="v")
plt.plot(accel_log, label="a")
plt.plot(z_log, label="z cooridnate")
# throttle and brake are scaled *10 to make them readable
plt.plot([10*t for t in throttle_log], label="throttle*10")
plt.plot([10*b for b in brake_log], label="brake*10")
plt.legend()

plt.show()
XGodina commented 3 years ago

Hi, @hh0rva1h

Thanks for that accurate test. I will test these new values.

jackbart94 commented 3 years ago

We have applied and tested the changes, let us know if it looks better now!

hh0rva1h commented 3 years ago

@jackbart94 Thanks very much, where has this been applied? Could you link the commit?

jackbart94 commented 3 years ago

You need to update the CARLA content, it's all explained in the documentation!

hh0rva1h commented 3 years ago

@jackbart94 Thanks, but still I'd like to understand what has been done, https://bitbucket.org/carla-simulator/carla-content/ has version control too, so it would be nice if you could link a commit.

Also imho it's not clear in https://carla.readthedocs.io/en/latest/build_update/#get-development-assets whether there is need to recompile Carla afterwards? My intuition tells me no, but ultimately I'm note sure.

jackbart94 commented 3 years ago

@jackbart94 Thanks, but still I'd like to understand what has been done, https://bitbucket.org/carla-simulator/carla-content/ has version control too, so it would be nice if you could link a commit.

It's been merged with some other stuff, @XGodina could you link the commit?

Also imho it's not clear in https://carla.readthedocs.io/en/latest/build_update/#get-development-assets whether there is need to recompile Carla afterwards? My intuition tells me no, but ultimately I'm note sure.

You need to update the content with UE closed, then just do make launch and you'll have the latest content!

germanros1987 commented 3 years ago

@hh0rva1h for simplicity just take the nightly build? http://carla-releases.s3.amazonaws.com/Linux/Dev/CARLA_Latest.tar.gz @XGodina could you confirm that these changes are present in the nightly build?

XGodina commented 3 years ago

Hi, @hh0rva1h That improvement is already in the new Release 9.10.

hh0rva1h commented 3 years ago

@XGodina @jackbart94 I just downloaded 0.9.10 and ran my script, I could not observe different behavior unfortunately:

Screenshot from 2020-10-01 23-33-23

jackbart94 commented 3 years ago

Please, make sure your content is actualized. There is clearly something wrong with that, since my graph is:

Figure_1

From the CARLA main folder, do ./Update.sh

hh0rva1h commented 3 years ago

@jackbart94 Thanks for the reply, however I did not compile from source, I do not have the hardware resources for that currently. All I did is fetch the binary release 0.9.10 and run the script. There is no Update.sh in the Carla main folder from the binary release though ...

hh0rva1h commented 3 years ago

@XGodina @jackbart94 @germanros1987 I just tried the nightly build, this issue is not fixed in the nightly build. As noted before I do not currently have the resources to build from source. Could you look into it again?

XGodina commented 3 years ago

@hh0rva1h I've checked the values and they're there. Have you downloaded the last content?

machar94 commented 3 years ago

This issue is of high interest to me as well. I will share my results when I can, but one of the things that I am going to investigate is changing the torque curve to be a flat line. This might also improve the performance of electirc vehicles in sim using PhysX in general. See: https://forums.unrealengine.com/development-discussion/c-gameplay-programming/64888-vehicle-with-no-drive.

hh0rva1h commented 3 years ago

@XGodina I just downloaded and extracted https://carla-releases.s3.eu-west-3.amazonaws.com/Linux/CARLA_0.9.10.1.tar.gz as well as the nightly build, both do not contain the fix ... How would I fetch the latest Content with the prebuilt binaries?

stale[bot] commented 3 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

hh0rva1h commented 2 years ago

@jackbart94 @XGodina @germanros1987 With Carla 0.9.12 things are imho worse:

0 9 12-1

Those extreme accelerations and decelerations are pretty unrealistic. Could you consider reopening this issue?

jackbart94 commented 2 years ago

Are you using synchronous mode?

hh0rva1h commented 2 years ago

@jackbart94 Yes I am, I am using the script from the original report.

jackbart94 commented 2 years ago

Then probably @DSantosO can tell you more about this once he comes back from holidays.

hh0rva1h commented 2 years ago

@jackbart94 Thanks, could you reopen and assign him in the meantime?

DSantosO commented 2 years ago

Hello @hh0rva1h, Thank you very much for your input. We will check this carefully.

hh0rva1h commented 2 years ago

@DSantosO Imho there are two problems here and imho the first problem is the more important one:

Problem 1

This affects every vehicle in Carla: After spawning a vehicle it takes a while until the car reacts to throttle, see https://github.com/carla-simulator/carla/issues/1640 This results in the insane spike in the beginning of my plot and has got even worse with Carla 0.9.12 (in 0.9.11 the spike only went up to 15): A1 There is a workaround for this behaviour, after spawning, manually shift gear to 1 and disable manual_gear_shift again:

vehicle.apply_control(carla.VehicleControl(manual_gear_shift=True, gear=1))
world.tick()
vehicle.apply_control(carla.VehicleControl(manual_gear_shift=False))

However with 0.9.12 this looks liks A2 Now there is a pretty bad negative spike down, which was not the case with Carla 0.9.11. And no, this is not a numeric error of the acceleration calculation, since the effect on the velocity plot can be seen clearly. That spike down should not happen. Would be great if you could root cause and address this.

Problem 2

In Carla 0.9.12 deceleration of the Tesla vehicle with throttle 0 is around 0.6g at 20m/s, this is to much even for regnerative braking when no throttle is given (this should be around 0.2 - 0.3 g, see https://electrek.co/2018/10/25/tesla-model-3-regenerative-braking-software-update/). A3 The workaround "physics_control.damping_rate_zero_throttle_clutch_engaged=physics_control.damping_rate_zero_throttle_clutch_disengaged" given in the initial report has drawbacks however: for 20m/s the throttle values drops from 0.72 to 0.31, so this is not a good solution either.

hh0rva1h commented 2 years ago

@DSantosO Whats the progress of this? With Carla 0.9.13 the plot looks like the following (just changed 0.82 to 0.7):

image

The deceleration of almost 1g at throttle = brake = 0 is still way to extreme imho.

stale[bot] commented 2 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

hh0rva1h commented 2 years ago

@jackbart94 @glopezdiest @germanros1987 Could you be so kind to share whether someone is working on this?

sbv198 commented 2 years ago

@hh0rva1h hello, is there any way to get these plot with respect to time? for my project this is really important thanks in advance

hh0rva1h commented 2 years ago

@sbv198 Sure, notice the line settings.fixed_delta_seconds = 0.045, this says that one tick is 0.045 seconds of simulated time. So one unit in the plot is 0.045 seconds.

sbv198 commented 2 years ago

@hh0rva1h

Thanks for the quick response!

sbv198 commented 2 years ago

@hh0rva1h

I tried to plot velocity curve with respect to time but it was un succesfull but could you please help me or if you have plotted it before can you share that piece of the code that would be of great help

thanks in advance

stale[bot] commented 1 year ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

dayaguec commented 9 months ago

Hello! I come from this issue #3906 and I have the exactly same problem with the Toyota Prius. I am trying to stop the vehicle with an ackermann controller and I am unable to stop it in the right place without suffering from the huge brake thing. My workaround is to force the controller to not brake for speeds lower that 1.0m/s but depending on the simulation state this is not solving the problem always.

I will appreciate some feedback,

Thanks in advance!