Engee documentation
Notebook

Simulation of automatic transmission operation

In this example, we will examine the Chart tool and the finite automata logic it implements, based on the principles of automatic gear shifting depending on speed.

On a simplified level, we will consider the differences in the operation of two types of algorithms - using states and using transition nodes.

At the beginning of the demonstration we declare an auxiliary function to run the model and proceed to the analysis of the implemented algorithms.

In [ ]:
# Подключение вспомогательной функции запуска модели.
function run_model( name_model)
    
    Path = (@__DIR__) * "/" * name_model * ".engee"
    
    if name_model in [m.name for m in engee.get_all_models()] # Проверка условия загрузки модели в ядро
        model = engee.open( name_model ) # Открыть модель
        model_output = engee.run( model, verbose=true ); # Запустить модель
    else
        model = engee.load( Path, force=true ) # Загрузить модель
        model_output = engee.run( model, verbose=true ); # Запустить модель
        engee.close( name_model, force=true ); # Закрыть модель
    end
    sleep(5)
    return model_output
end
Out[0]:
run_model (generic function with 1 method)

At the top level, the model contains two gear shifting algorithms. The inputs for both charts are identical. The tables specify the speed thresholds at which to either upshift or downshift, and the current speed value itself, given by a sinusoid.

image.png

Next let's look at each Chart individually. The top block uses node logic and produces a +-1 gear shift parameter depending on the speed, which allows you to perform a gear increase or decrease, which is stored in the loop. The initial gear value is 1 in both cases.

image.png

In the second case, depending on the speed, we switch between different states in which a suitable gear is set to match the input speed mode.

image.png

Now let's run the model itself and analyse the logged values.

In [ ]:
run_model("car") # Запуск модели.
Building...
Progress 0%
Progress 0%
Progress 26%
Progress 100%
Progress 100%
Out[0]:
SimulationResult(
    "GearChart.gear" => WorkspaceArray{Float64}("car/GearChart.gear")
,
    "ShiftChart.shift" => WorkspaceArray{Float64}("car/ShiftChart.shift")
,
    "Bias.1" => WorkspaceArray{Float64}("car/Bias.1")
,
    "gear" => WorkspaceArray{Float64}("car/gear")

)

Read the logged data from simout. In this case:

v is the speed of the vehicle;

shift - shift parameter for the gearbox algorithm implemented using nodes;

gear_node - gear values for Chart using nodes;

gear_state - gear values for Chart with states.

In [ ]:
v = simout["car/Bias.1"];
v = collect(v);
shift = simout["car/ShiftChart.shift"];
shift = collect(shift);
gear_node = simout["car/gear"];
gear_node = collect(gear_node);
gear_state = simout["car/GearChart.gear"];
gear_state = collect(gear_state);

Now let's move on to analysing the obtained data. Let's start with the speed. As we can see from the graph below, the speed is set as a sine wave in the range from 0 to 120. The initial value of the velocity is not zero. It is set for the purpose of demonstrating the differences between the algorithms using nodes and states.

In [ ]:
plot(v.time, v.value)
Out[0]:

Next, let us analyse the system with the application of nodes. As we can see, the initial value of this system at the first step is not the first transmission, but the second. This is due to the fact that the node immediately reported the counter increment.

In [ ]:
plot(gear_node.time, gear_node.value)
plot!(shift.time, shift.value)
Out[0]:

Now let us turn our attention to the system implemented on the basis of states. The initial transfer value is 1. This is because in the case of states, in the absence of initialisation logic, we will start with the input state and then go through at most one state per clock.

In [ ]:
plot(gear_state.time, gear_state.value)
Out[0]:

Let us now compare the values calculated by the different gearbox simulation systems. As we can see from the results below, the first two clock cycles are different. This is due to the peculiarities of the logic processing described above.

In [ ]:
difference = gear_state.value-gear_node.value;
print("Различие в логике переключения передач: "*string(difference[1:3]))
Различие в логике переключения передач: [-1.0, -1.0, 0.0]

Conclusion

In this demonstration we have analysed the differences in the logic of nodes and states. With this example, we got a visualisation of how the different algorithms implemented using the Chart block are handled.