Railcraft

Railcraft

34M Downloads

Locomotives switching direction

Vliro opened this issue · 17 comments

commented

I've tried to solve this for some time, but I just cannot figure it out. I've built a rather large rail system to deliver ores, mob farm etc which in theory should work. However, it happens quite often that I find a locomotive astray which is running backwards. I cannot figure out the logic behind it. For instance, I had an advanced miner(running infitech2) and a locomotive associated with it, and it worked just fine. When I moved it further away for new chunks it happens constantly that it reverses direction and completely kills any output from the miner. One live example I found was that it switched direction when it positioned itself under the fluid loader at the miner itself(not the station), which I managed to catch in time.

Since locomotives often change direction when they are newly restarted, I thought it was something along the lines of that. Though, I just cannot find any discernible pattern. I'll attach screenshots of the station + the miner.

I haven't found a lot of info as to why locomotives switch direction from the first place, which might help.
http://imgur.com/a/b1o85


commented

This bug from 1.7.10 will never be fixed, but the following information might be useful for future readers:

I also encountered this bug while playing the same (old) modpack.
Although I didn't isolate it either, it appears to occur on corners next to boarding tracks.
Boarding tracks used with trains can cause parts of the train to oscillate, stretching and contracting the links, and when this happens near a corner, it is consistent with CJ's observation that locomotives can flip when turned 90 degrees for a couple of ticks.

When a train is pulled by a locomotive, boarding tracks are redundant, anyway, and can be replaced by lockdown tracks (different mode of the same track).

commented

Had a 2 month build based on railcraft. After getting everything implemented, my locomotive flips around every couple hours- completely killed the entire project.

Is this a bug that can/will never be fixed?

It essentially renders all trains useless as they will bug out over time (some quite frequently). Unsure why this was marked priority-low for that reason.

commented

@Suterusu1337 marked low priority because I don't have enough information to fix it. I spent weeks just getting to the current point. Orientation tracking was very nearly a showstopper for implementing Locomotives, I literally spent weeks on that single issue.

To fix it, I need more info. I also need someone to provide me a reproducible setup, I've had no luck creating one. I need to know what the conditions of the flip were. Did it occur on a corner? On chunk load? I just don't know.

Corners are tricky because minecarts have to flip on corners, its how the system works. The hard part is making sure it flips in the correct direction.

As for collisions, I haven't found that code yet, so I have no idea.

See #972 for a more specific instance being fixed just today.

commented

I have a pretty repeatable build currently, but I can't reproduce while watching. It happens while pulling an admin anchor cart as well, so unsure on the chunking.

Is there a way to manually correct the problem that anyone knows of? As in, detecting it is flipped and resetting the orientation via another track type?

commented

If I had a reliable way to detect flips that didn't return false positives on corners or direction of travel changes....we wouldn't be having this conversation. =P

Well... assuming it wasn't serialization related, that's a completely separate can of worms.

commented

Will update findings in 972

commented

As for repeat-ability. I really need a build that can produce a flip on demand to have any reasonable chance of finding the problem. Sadly as I've said, no such luck.

commented

I did discover some interesting findings yesterday while playing around with derail mechanics. If I flip the direction of travel 90 degrees for a couple of ticks, when it switches back it will be reversed. That's probably just the corner mechanics doing their thing though.

commented

This is an issue I come across a lot with my rail systems. I'm not very familiar with Minecraft Modding (I'm trying to make one, but struggling to understand how), but I have a possible solution idea to implement in the code:

Diagram:
http://imgur.com/HyNeJ18

In theory,
The connection between the links of two carts is always the shortest distance between all links. Assuming a standard train (Cart A is linked to Cart B between cart_a(rear) and cart_b(front)), then the distance of cart_A(rear) is less than the distance of cart_a(front) with cart_b(front) and cart_a(rear) with cart_b(rear).
d[cart_a_r, cart_b_f] < d[cart_a_f, cart_b_f] AND d[cart_a_r, cart_b_f] < d[cart_a_r, cart_b_r]

First, we should maintain link integrity, as in, location integrity, meaning that when two carts are connected, the location of the connections remains constant (The Front link is always the front, and the Rear link is always the rear link of the cart.

Upon updating, verify the distances between links and flip if necessary.
Continuing example above:

IF d[cart_a_f, cart_b_f] < d[cart_a_r, cart_b_f] THEN flip cart_a
IF d[cart_a_r, cart_b_r] < d[cart_a_r, cart_b_f] THEN flip cart_b

This process could be sped up by verifying only Link A of each cart. If a cart doesn't have a link in the rear, then move to the next cart.

// Verify carts are facing correct direction
protected void verifyCartDirection( Train train ){
    // Ensure length of train is at least two.
    if( train.getLength() > 1 ) {
        // Iterate through train, ignore last cart
        for( int i; i < train.getLength(); i++ ){
            // Check if cart has connection on the rear link.
            if( train.getCart( i ).getLinkRear().isConnected() ){
               // If distances between CartA.LinkRear and CartB.LinkFront > CartA.LinkFront and CartB.LinkFront 
                if( get3DSquareDistance( train.getCart( i ).getLinkRear().getGridLocation(), train.getCart( i + 1 ).getLinkFront().getGridLocation() )
                     > get3DSquareDistance( train.getCart ( i ).getLinkFront().getGridLocation(), train.getCart( i + 1 ).getLinkRear().getGridLocation() ) )
                    //Flip the front cart
                    train.getCart( i ).flip()
        }
    }
}

//Returns the 3D distance before the points are square rooted. (Saves time)
public float get3DSquareDistance( Point3D point1, Point3D point2 ){
    return Math.pow( point2.x - point1.x, 2 ) + Math.pow( point2.y - point1.y, 2 ) + Math.pow( point2.z - point1.z, 2 )
}

The code assumes only if the train is facing a single direction (forward). I will update on a more general workaround when I get a chance. I wrote the code directly in GitHub; so, I apologize if there are any errors.

commented

Your core assumption may actually be false: "The connection between the links of two carts is always the shortest distance between all links."

There are a number of edge cases where this isn't necessarily true. Elevators, lag, corners, etc...

F and R are not really good names since only locomotives have orientation, so I'm going to stick with A and B.

Additionally, assuming two unlinked carts, how do you decide whether to link to coupler A or B? Check all four permutations for shortest distance? I guess that could work. But then again, as I said before, only locomotives actually track orientation at all. Normal carts randomly flip 180° every time they go around a corner or get loaded from disk. The orientation tracking that locomotives use is a buggy hack which is why we are seeing this issue in the first place. This is not a capability that is supported by Mojang code.

commented

I use F and R purely for readably - I understand they are terrible names -I didn't want to get too confusing with the naming above in the pseudo-code. I agree with A and B.

If we really wanted to, could force cart orientation integrity - even for normal carts? If they do a 180°, we could force it back. I know it's not ideal, but neither is the fact they rotate at all.

If we go around a corner, the shortest distance is still between the two points; although a two-block 180° might be an issue, but maybe the length of the cart is great enough to not be an issue?

Do locomotives have a habit of flipping on elevators? I can't honestly say I use them enough to determine the answer. If not, then upon reaching the top or bottom, the distance falls into play, even if you turn at the exact top. Maybe a ignore variable could be implemented on elevators to skip the check.

If there is lag, it would corrected on the next update, - or am I missing something? Again, new at this. I understand that if we include an intended_direction_vector variable for the direction we want the train to move on the next update, it might still be prone to erroring in the case of lag.

But now I come across this next issue: What if CartA and CartB flip on the same update while CartC remains in the corrected orientation - how could we do the check then?

commented

Thanks for the info, I inferred it being a cause of mojangs lack of minecart implementation? Is there any way to guard against this issue, since it is pretty problematic due to my cargo setup.

commented

@Vliro it most likely happens when the Locomotive is loaded from the disk, so reducing the number of times that happens (ie with chunkloaders) might help. But that is only an assumption on my part. I could be completely wrong about when it happens. Determining precisely what happens when it flips would go a long way to isolating and fixing the issue (if it's fixable at all).

commented

@MajorR I can only add orientation tracking to minecart entities that I control. Minecarts from other mods are out of luck, and one of my design constraints is that Railcraft works with any minecart from any mod.

commented

Well I don't know if any one is aware of this. This is not all ways the case. The trains changing directions for me any way has been 2 things. 1) Corners. Stopping trains on corners to load or unload or just stopping them on a corner, That this will happen. Try not to stop any of the trains on a track that has a curve.

  1. Running into other trains. Some times I have see this where a train is stopped on the track for what ever reason. and a 2nd trains comes up from behind and the trains hits the 1st train. The train changes direction and heads back the way it came. (This is not very often)

This is why I asked CJ to remove the auto reverse from the trains. This would stop them from changing direction. if you look at this image,
Problems like this can cause the trains to change direction
https://www.flickr.com/photos/126613374@N08/
All so these items can cause headaches for Minecraft Players that run Railcraft.
https://www.flickr.com/photos/126613374@N08/18045683784/in/dateposted-public/
https://www.flickr.com/photos/126613374@N08/16717136814/in/dateposted-public/

This one is a no no. Never do any thing like this. It can really cause problems
https://www.flickr.com/photos/126613374@N08/17319536605/in/dateposted-public/

The 1st one I posted is all ways going to be my problem. I just have to remember not to have your trains stop for any thing on curves and/or corners

commented

I think the reversing on obstacles is a vanilla momentum thing, I'd need to investigate. Furnace carts do the same thing.

commented

Well you did some last summer. You never got any where with it. After watching them and making some test my self. That's what I came up with. I was going to make a video on it and never did.