esmini / esmini

a basic OpenSCENARIO player
Mozilla Public License 2.0
769 stars 220 forks source link

Ghostdriver and change of driving direction #384

Open Lunarix opened 1 year ago

Lunarix commented 1 year ago

Hello, I am having some trouble using the esmini-ghostdriver and changing the driving direction in a scenario. I am using the SE_GetRoadInfoAlongGhostTrail() function to get Ego's next position & speed. I attached the regular xosc files and the xosc files using the ghostdriver in the zip file. The _temp scenario's contain the ghostdriver scenarios.

Let's assume the scenario below: scenario_graphic The Ego vehicle will drive forward until it will hit the circle. This is a DistanceCondition that triggers driving backwards. The vehicle should brake to standstill and then drive reverse. I can define the transition dynamics differently how fast the vehicle should drive backwards.

1. Working scenario Scenario change_direction_works_temp.xosc uses a very very fast change of directions: `

` No vehicle can brake that fast so that my vehicle will overshoot the ghostdriver's estimated turning point. I get a valid reverse trajectory afterwards so that my vehicle will try to drive backwards as fast as possible. **2. Not working scenario** Scenario change_direction_false_temp.xosc uses a slow change of directions: ` ` The vehicle will slow down very slowly. It will even pass the other vehicle by a few meters. Right before hitting the turning point the ghostdriver will always return +-0 ghost_speed information. It is constantly switching between a small positiv ghost_speed value and a small negative ghost_speed value. That's why my vehicle will never reach that last point and never start driving backwards. I am currently using a ghostdriver distance of ~0.2m but also changing that to a higher value ~2m did not improve the behaviour. The switching point is then just a bit more infront of the vehicle. Is there any configuration that I can make to improve driving at these turning points? I've also attached the original xosc files that are both runnable using the original esmini-driver and dynamics. Thank you! [ghostdriver_scenario_change_direction.zip](https://github.com/esmini/esmini/files/10569989/ghostdriver_scenario_change_direction.zip)
eknabevcc commented 1 year ago

Thanks for the report! This is a bit tricky. Let's try sorting out step by step.

Changed sign of speed during action First: Your scenario made me aware of an issue I never thought of before: Speed changes sign during the action with dimension = distance. I.e. speed going up or down to 0 and then change direction.

image

Consider changing from +5 to -2, over a distance 10 meters. What does it mean? In previous implementation the integrated displacement would contain one positive and one negative part, resulting in to less displacement. Even worse, consider changing from +5 to -5. The integration would add one equal sized positive and negative parts resulting in zero displacement.

By commit 61aaa030ec7a9bce74d41af9799966e15b989ed6 this is changed so that always the absolute value of displacement is used, adding magnitude of the two parts.

It's not obvious what's correct, but I feel this is the best option. But I'm willing to reconsider of course :)

Ghostdriver stuck around zero I understand this happens in the scenario that's using dimension = rate. I can't reproduce that issue. Can you provide more details, e.g: Do you run fixed timesteps? In that case what timestep?

Following ghost by time or distance There are two ways of using following a ghost. You can find some info in User guide - The ghost concept. And this example makes use of both: test-driver.cpp (also part of User guide - Hello world).

I don't know what mode you're using, but the distance mode will probably be really strange in combination with a ghost moving back reverse along it's original trajectory. In this use case I think the time mode is better - at least if ghost is actually performing the speed change action.

Let's start with these comments. If possible, please checkout latest version from master which includes the "speed changing sign" fix and see if it affects your scenario.

Lunarix commented 1 year ago

Hello @eknabevcc

I've integrated the latest master and tested with that version.

Changed sign of speed during action I am not sure if the changes helped. I am using this scenario: esmini.zip Within there the SpeedAction is triggered after 3 sec's simulation time: `

` When the action is triggered I am using the distance based ghost driver and receive the speed at 1m ahead (SE_GetRoadInfoAlongGhostTrail(0, 1.0f, &roadInfo, &ghost_speed);). I thought the speed **should be 2.7777** there but **it its 0.0153087862**. I am not sure if I am missing something there. **Ghostdriver stuck around zero** I am using ONLY the **SE_GetRoadInfoAlongGhostTrail** so far NOT the **SE_GetRoadInfoGhostTrailTime** (see explanation below). I could record this video showing the issue: https://user-images.githubusercontent.com/38215884/217775069-d11459cd-096b-419c-9242-12153c574f46.mp4 I am using multiple distances and colorize them red if the speed is >0 and green if the speed is <0. It constantly changes the sign & are located infront of the ego so that the vehicle not really doing anything. **Following ghost by time or distance** I've used the same approach as you did in the examples, using time and distance based ghost-mode alternatly. But then for me it seems that the time-based ghost is not always updated to the current position of the ego-vehicle. The scenarios with the backwards driving works, but after a few meters backwards this happens: ![distance_vs_time](https://user-images.githubusercontent.com/38215884/217778083-220bdd2e-da6d-4cd9-84b1-9a1f31e3b6a1.png) I thought that the points should be very close to each other and it should not matter if I use time or distance based ghost. But the time based ghost does not seem to update correctly to the current ego position, tho it works for the distance based ghost. Am I doing something wrong here? Time based ghost calls: `std::cout << "Time: " << SE_GetSimulationTime() << std::endl; std::cout << "Requested time " << SE_GetSimulationTime() + lookAhead << std::endl; // Time based look ahead SE_GetRoadInfoGhostTrailTime(0, SE_GetSimulationTime() + lookAhead, &roadInfo, &ghost_speed);` will return something like: Time: 2.92 Requested time 2.99 Also I tried this scenario highspeed_ghost.xosc showing the problem even better: [highspeed.zip](https://github.com/esmini/esmini/files/10695842/highspeed.zip) I've used a acceleration that no vehicle dynamics can ever make: ` ` After a short time this is what I get from distance & time based ghost ![distance_vs_time_highspeed](https://user-images.githubusercontent.com/38215884/217780489-d8d3721a-f1e9-41d5-87c9-febd55c02bb4.png) The time based ghost is just "driving away" and does not seem to update on the position of the ego (that can not accelerate so fast). After a few secounds the time-based ghost trajectory points are out of the window already. Do I have to update the time based ghost differently? Thank you!
eknabevcc commented 1 year ago

First a clarification regarding the fix: Your initial scenario "change_direction_works.xosc" contained an action changing speed from +5.555556 to -5.555556. With the previous behavior it would not work with dynamics dimension = distance, simply since with linear transition from and to a speed of equal magnitude but different signs, the net displacement is always 0. The updated behavior is to count for absolute displacement.

distance_small

But as you say, I don't think it matters for your issue. Nonetheless I was glad to discover this edge case!

Unexpected small speed Ok, then let's look at the unexpected small speed: The problem, I think, is that when the ghost starts moving, it is not moving from it's original position. Instead it's jumping to a point ~10 meters away. So the resulting trajectory/trail will start at the original location with a registered speed of 0 km/h. The next point is 10 away and has registered really low speed - since that point is at the beginning of the speed action over 1m. So, when interpolating for the distance = 1 you will get something like 1/10 * "small speed", which in your case (depending on timestep size) ends up at 0.015.

image

The recommendation is simply to ensure ghost starts moving from it's original position. Motion continuity is in general a good thing, so I don't think this strategy implies any bad limitations.

See modified scenario: acc_ghost-mod.xosc.txt

or even this version, which makes the scenario less complex by moving trajectory and speed actions to init section (but of course loose the possibility to time the actions with triggers): acc_ghost-mod2.xosc.txt

You can run them with this application code (modified test-driver.cpp example): test-driver-mod.cpp.txt

Should look something like: img1

Finally regarding getting stuck I can't reproduce this behavior. But I have one suspect: Can it be that ghost do not have enough head-start, so that Ego catches up with ghost and hence has no trajectory to follow? Anyway, if you want Ego to follow ghost movements, including going forward and reverse alternately, you basically need to use the time based follow. That one will basically look-up where ghost was at given time stamp. The distance based method is very different: From Ego current position look some distance along ghost "foot print" trail, which will be more or less undefined if ghost has been moving back and forth.

For more info on ghost concepts, please see User guide - The ghost concept.

With this info, I hope you will find a solution. For further investigation we would need your application code for reproduction, or at least minimum application code reproducing the issue.

BTW: Thanks for good report, I appreciate the detailed description and video clip which usually helps understanding and investigation on our side 👍