sumo icon indicating copy to clipboard operation
sumo copied to clipboard

speedFactor not adjusted when switching vehicle type

Open luifire opened this issue 1 year ago • 19 comments

When I switch a vehicles type using traci.vehicle.setType(vehID, 'B_VEHTYPE'), and the new type has a different speedFactor then the previous one, the speedFactor is not updated.

I made a small example showing the issue: vehicle_type.zip

Thanks and best luifire

SUMO-version: traci.getVersion() -> (21, 'SUMO v1_20_0+0229-9bb6e39c011')

operating system: Win10

luifire avatar Jun 21 '24 12:06 luifire

generally speaking, the vType only defines a distribution from which each vehicle draws it's individual speedFactor. I think in some contexts it's rather useful that the vehicle doesn't re-roll this value when switching type. You can always call traci.vehicle.setSpeedFactor to modify the individual value.

namdre avatar Jun 21 '24 12:06 namdre

The no re-rolling part makes sense. However, I am switching the type quite a lot and the communication seems really expensive. Thus I would prefer not to call setSpeedFactor each time I do a type switch. It is kind of a: in some scenarios drivers behave well, but in others they speed.

I suppose the behavior that would make the "most sense" is that the speed factor of each vehicle is stored depending on its type. But I get that this would imply quite some changes. Do you see any other solution?

luifire avatar Jun 21 '24 12:06 luifire

I agree with @namdre if the type really defines a proper distribution (not only a single value) and the chosen value of the vehicle has a non-zero probability in this distribution. But if not I would also prefer the consistency of having a value which fits the one (or the range) defined in the type. vType switching is a dangerous business anyway, so I don't see a point in protecting the user more than needed here. One problematic side effect though is that you cannot switch back easily to the value you had before.

behrisch avatar Jun 21 '24 12:06 behrisch

The no re-rolling part makes sense. However, I am switching the type quite a lot and the communication seems really expensive.

Did you consider using libsumo if performance is an issue?

behrisch avatar Jun 21 '24 12:06 behrisch

I haven't. Thanks for pointing this out. :)

luifire avatar Jun 21 '24 13:06 luifire

Can we maybe reopen this issue, because as for @luifire this also does NOT work for me, actually ;)

@behrisch mentioned:

"But if not I would also prefer the consistency of having a value which fits the one (or the range) defined in the type."

Regarding the distributions re-roll, we probably all agree, that this would be a bit tricky, so you could maybe leave it at it is. But in terms of vType switching for individual vehicles, as a user I would definitely expect the new speedFactor to be applied.

For example, since I use different speedFactors for different vTypes when deploying the ToC device, I'd don't see why it should not change automatically. Tracing this via traci manually is a pain.

robertalms avatar Jun 28 '24 14:06 robertalms

We could make a special rule for vTypes with unambiguous speedFactor (where speedDev="0"). I wouldn't mind having them overwrite the vehicle-speedFactor upon type switch. What do you think @behrisch

namdre avatar Jul 01 '24 06:07 namdre

If we actually go forward with this, I would vote for a re-rolling.

The reasons being:

  • Having special vTypes that allow for a type switch where the speedFactor changes, which can be acquired by setting speedDev="0" seems too complicated to explain for other developers facing this problem. Whereas: if you need to switch vTypes and your speedFactor is random, we will roll the dice seems straight forward to me.
  • I do think that people will speed in different manners, when something changes (e.g. during night, after a traffic jam, after an argument in a car, driver within the same car changes, ...). So it would make sense (to me) to have a new speed factor for the same car.
  • Statistically, I would hope that the re-rolling keeps most expected values the same.

luifire avatar Jul 02 '24 08:07 luifire

I would find it counterintuitive to have a driver that is speedy in the morning to become slower-than-average in the evening. So my alternative proposal would be to compute the new speedFactor so that it fits onto a similar point in the new distribution: I.e. if the old speedFactor was half the stdDev above the exepected value, the new speedFactor should be half the new stdDev above the new expected value. My old suggestion for a new distribution with speedDev=0 then becomes a special case of the new proposal. You get to set a new value when you change types and it will also follow the distribution just as before but in a more consistent manner.

namdre avatar Jul 02 '24 09:07 namdre

IF the initial speedDev is 0, we need to roll the dice later when we have the first non-0 speedDev

behrisch avatar Jul 02 '24 11:07 behrisch

Thanks for doing this so quick. Seems to be working just fine in my local tests...

robertalms avatar Jul 03 '24 12:07 robertalms

A new speed factor gets assigned as expected.

What I do in my simulation is to switch between a speed factor of 1 (vehicle drives exactly as expected - e.g. a self driving vehicle) and then go back to person-driving mode, i.e. a random speed factor. Switching between these modes does not seem to preserve the deviation from the mean thing. I am using normc(1.0, 0.3, 0.1, 1.5).

traci.getVersion() -> (21, 'SUMO v1_20_0+0991-fc540e9834b')

luifire avatar Jul 04 '24 09:07 luifire

Switching between these modes does not seem to preserve the deviation from the mean thing.

If you switch from a non-random distribution (speeDev = 0) to a random one (speedDev != 0) then the speedFactor is resampled anew as per @behrisch 's suggestion. This means the speedFactor will not be stable over multiple switches. (The information about whether the car is slower or faster than average is "destroyed" when switching to a non-random distribution. To fix this we would need to introduce another member variable that can carry over the information from the last non-random distribution.

Or maybe I misunderstood your problem. In this case please elaborate.

namdre avatar Jul 04 '24 14:07 namdre

Actually I also thought that once we did a roll it will stay stable for the rest of the lifetime of the vehicle. But I agree this will need storage inside the vehicle. We have another problem here because it may also happen that the re-used distPoint violates the boundaries of the new distribution. I re-open because there seems to be more stuff to do

behrisch avatar Jul 05 '24 12:07 behrisch

As I understood @behrisch , this would only hold if the initial speedDev is 0. Switching back and forth hasn't been discussed.

From your post, I presume you have not yet introduced a new member variable, you probably just compute the distance to the mean of the distribution. Is that correct?

I suppose what works for me for the speedDev=0 case is to just have a really small speedDev instead.

Where someone might end up in a problem with the current solution: When you switch between a normal distribution $N$ and a truncated normal distribution $M$, where $M$ has really small bounds, then, when switching back to $N$, you will end up in a truncated normal distribution as well.

(Kind of what @behrisch just wrote, I was just a bit too slow)

luifire avatar Jul 05 '24 12:07 luifire

w.r.t. truncation I see to distinct problems here:

  1. what value to use when the old distPoint violates the new bounds a) use the boundary value (this is being done at the moment but obviously causes a bunch of values to fall on the boundary) b) ignore the boundary c) resample the distribution

  2. how to avoid information loss when switching back to a non- or less-truncated distribution? (only an issue with a) and c). Storing more information would help but for strategy c) we might need to store more than one distPoint

namdre avatar Jul 08 '24 11:07 namdre

Just a suggestion: as I understand you, you don't want to introduce a new member variable (which is fair enough). In case you have a bit-mask with an empty bit, one could simply store if we are left or right of the mean and then resample with every type switch.

This way, a person speeding would still speed and vv.. At least from my experience, this matches reality.

luifire avatar Jul 08 '24 13:07 luifire

one could simply store if we are left or right of the mean and then resample with every type switch

Once we have to deal with boundaries it might happen that one distribution has all valid values to the left of the mean and the next distribution only has values right of the mean.

  • an alternative discussed with @behrisch could be to store the relative point within the boundaries mapped to [0,1]
    • this doesn't work to well when switching between distributions with and without boundaries
    • it can introduce a weird bias if both distribution shapes within the boundaries are different (i.e. normc(1,0.2,0.1,1) has lots of weight on the right of the distribution whereas normc(1,0.2,1,2)` has most of the weight on the left of the distribution)

Mathematically, the clean solution would be to preserve the point in the cumulative distribution function (the likelihood of having a lower/higher value than the current speedFactor is preserved through switching).

namdre avatar Jul 08 '24 14:07 namdre

Once we have to deal with boundaries it might happen that one distribution has all valid values to the left of the mean and the next distribution only has values right of the mean.

I meant the expected value, not the mean-parameter. So for a type switch: one would sample a value, check if the sample is left or right of the expected value, and resample, if you are on the wrong side.

The truncated normal distribution even has a pseudo-closed form expected value: image

Note: this is just a suggestion, I am not saying that this is the best solution.

luifire avatar Jul 09 '24 08:07 luifire

one could simply store if we are left or right of the mean and then resample with every type switch

Once we have to deal with boundaries it might happen that one distribution has all valid values to the left of the mean and the next distribution only has values right of the mean.

  • an alternative discussed with @behrisch could be to store the relative point within the boundaries mapped to [0,1]

    • this doesn't work to well when switching between distributions with and without boundaries
    • it can introduce a weird bias if both distribution shapes within the boundaries are different (i.e. normc(1,0.2,0.1,1) has lots of weight on the right of the distribution whereas normc(1,0.2,1,2)` has most of the weight on the left of the distribution)

Mathematically, the clean solution would be to preserve the point in the cumulative distribution function (the likelihood of having a lower/higher value than the current speedFactor is preserved through switching).

Mapping it to (0, 1) makes sense to me as well. You won't run in the problems mentioned if you do it using the cumulative probability. I.e. if you want to go from any distribution $A$ to $B$, you can map it to the cumulative probability using the $CDF$ of $A$ (which gives you a value between 0 and 1) and transforming it back to $B$ you use $CDF^{-1}$ of $B$.

The $CDF^{-1}$ of a truncated gaussian exists and can be found here, chapter 1.4 https://people.sc.fsu.edu/~jburkardt/presentations/truncated_normal.pdf The rest is on Wikipedia.

But you will still have a problem with a variance 0 (i.e. Dirac) distribution if you don't safe the cumulative probability to a vehicle. (Which btw would only need to be done once). But one could work its way around it by setting the variance to some very small number.

luifire avatar Sep 13 '24 13:09 luifire