Custom python script trouble

Hello, I’m trying to make algorithm that by adding some parameters of train, I can calculate the maximum speed at each segment of the profile…

What I have as input:

  • I have calculated torque at each speed at 0 grade. For example at 0kmh I have 16.32 dN/t, at 10kmh I have 15.78 dN/t…

  • I have extracted the grade of the profile at each station_interval(I’m dividing it by 10m parts)
    Imgur: The magic of the Internet

  • I have extracted all stations at station_interval(I’m dividing it by 10m parts)

And now I’m trying to make at each station I’m trying to get the exact torque for the grade, then calculate the time that train needs to pass this station_interval(for the example is 10m) and then calculate the final speed at the interval. Then this final speed I need to use it for the next interval.


I think thats all about the working principle

Because every different alignment has different length, I will have different segments and I can not create loop like in the screenshot thousand of times…
I have tried by simple nodes to create the loop but not so successful.
I’m now trying by python script, but I’m again in the middle of nowhere because I do not have any experience with python.
Thats what I reached with little help of chatGPT:

import math

def estimating_speed(station, station_slope, station_interval, torque, torque_interval, start_speed):
    """
    Estimate the train's speed at the end of each station.

    Args:
        station (list): List of station points (integer values).
        station_slope (list): List of slopes corresponding to station points (in %).
        station_interval (int): Distance between stations (in meters).
        torque (list): List of torque values (in dN/t) at specific speeds.
        torque_interval (int): Speed interval for torque values (in km/h).
        start_speed (float): Initial speed of the train (in km/h).

    Returns:
        list: End speeds for each station.
    """
    
    def get_exact_torque(speed, torque, torque_interval):
        """
        Calculate the exact torque for a given speed using linear interpolation.
        """
        if speed <= 0:
            return torque[0]  # Return the first torque value if speed is below the minimum
        elif speed >= (len(torque) - 1) * torque_interval:
            return torque[-1]  # Return the last torque value if speed exceeds the max

        # Find the lower and upper bounds for the given speed
        lower_index = int(speed // torque_interval)
        upper_index = lower_index + 1

        # Speeds corresponding to the indices
        lower_speed = lower_index * torque_interval
        upper_speed = upper_index * torque_interval

        # Torque values at these speeds
        lower_torque = torque[lower_index]
        upper_torque = torque[upper_index]

        # Perform linear interpolation
        exact_torque = lower_torque + (speed - lower_speed) * (upper_torque - lower_torque) / (upper_speed - lower_speed)
        return exact_torque

    # Initialize outputs
    end_speeds = []
    current_speed = start_speed  # Set initial speed for the first station

    # Iterate over each station
    for i in range(len(station)):
        # Step 1: Calculate exact torque for the current station
        exact_torque = get_exact_torque(current_speed, torque, torque_interval)

        # Step 2: Calculate a realistic station_time based on torque and distance
        # Let's assume that torque affects the change in speed with a factor, e.g., speed increases with torque/200
        station_time = station_interval / (exact_torque / 200)

        # Step 3: Update end speed with a realistic delta
        speed_delta = exact_torque * station_time / 1000  # Factor for scaling the speed change
        end_speed = current_speed + speed_delta

        # Append the result and update the current speed for the next station
        end_speeds.append(end_speed)
        current_speed = end_speed  # Update for the next station

    return end_speeds

# Example Inputs
station = IN[0]
station_slope = IN[1]
station_interval = IN[2]
torque = IN[3]
torque_interval = IN[4]
start_speed = IN[5]

end_speeds = estimating_speed(station, station_slope, station_interval, torque, torque_interval, start_speed)

# Call the function
OUT = end_speeds

Do you have any ideas how to make it work?
Thank you!

Hi Aleksandar, welcome :wave:

I don’t think you are going to have much luck with ChatGPT and python straight out of the gate. I would try and learn the basics like here

I think it would be possible to do these calculations in Dynamo, we just need to know the formulas which are not apparent from your screen shots
How are you calculating torque?
Are your formulas based on the kinematic equations?
What are your constants?
For example to calculate time t given initial velocity Vi, acceleration a and distance d the formula is solving the quadratic equation i.e.
image

If initial velocity is 0, time is calculated with this formula
image

Hello Mike!

Yes, even in the beginning I was sure that chatGPT is not going to be so useful.

I’m using these 2 formulas:

Problem is that when moving along the profile, you have different grades. So even with same speed you will have different torque force(it is “r” in the screenshot) on different grades… I have divided the profile in section of 10 meters, so I can have the distance fixed and just to determine the speed and time. Here comes my first problem-I can not manage to add the new speed as starting speed in the next station and make it in loop until it reaches the maximum speed. Then when it reaches the maximum speed it should decide if grade is low enough to continue with max speed or the speed will drop.

Final diagram should be something like that, but if I have the speed I can manage the graphical part:


I’m already trying to do something alone, but every beginning is hard :smiley: so one friend helped me, but I can not disturb him everytime. Here is what we have reached:

Some comments on the code
You can post formatted code using the </> menu item

If something is an absolute requirement use assert
Line 15: assert len(torque_list) == len(speed_list)

Now create a dictionary like this
mapped_speeds = dict(zip(speed_list, torque_list))

As I have noted before if you use a formula to generate the torque value this is not required and is a clunky way of getting non-discrete values

trip_time is not used

enumerate works well when iterating over a list, also if you are starting at index 1 and going to the end you could use something like this

for i, dist in enumerate(station_dist[1:], 1):
    dist -= station_dist[i - 1]

It can be assumed that dist will always be above 0 so the while statement is unnecessary and you can eliminate the break on line 36 as it is not required

move line 23 station_time = 0 to be outside the for loop? otherwise it resets every time

line 27 current_speed + speed_interval - current_speed ??

line 28 & 31
station_time += time

Edit: Fixed slicing error

1 Like

Thank you Mike!
I already managed to fix and improve it. Sorry for not updating the thread…
It is working as I expected now.

1 Like