Jump to content

Detecting objects from child-prims of linksets


arabellajones
 Share

You are about to reply to a thread that has been inactive for 1489 days.

Please take a moment to consider if this thread is worth bumping.

Recommended Posts

I know that the SLRR trains use a script in the root prim to detect the "Guide" prim in the track. These scripts are very old, and much is hardly documented: a few comments and  maybe something about variable-names.

Is there some way of getting the same sort of position vector between the nearest "Guide" prim and a child prim in the linkset. There is real-world rolling stock which, when scaled in proportion to the SLRR track gauge, is over 30m long. If a model were behaving like the real vehicle, there would be two points following the track, not the single central point of a root-prim. So, if one prim is still the root of the linkset, how can the position vectors be generated for the other prims?

I know that there are train-things on the SLRR which are a single-vehicle/linkset that bends to follow the track. How might they work?

Link to comment
Share on other sites

It involve a lot of complicated geometry calculations that I do not wish on anyone. I've tried doing what you are mentioning, I haven't succeeded yet.

Real world trains are far too long and unwieldy for the typical SLRR turn radius.

Real world locomotives have some pretty large turn radius requirements that don't really work when the world is split in 256m regions.

In addition, SLRR rails are EXTREMELY wide apart compared to the real world (excepted india), standard RL rail gauge is 1.435m in most of the world, SLRR gauge is ~40 wider.

Link to comment
Share on other sites

One thing you're missing is that the model railroading hobby has some of the same space problems that the SLRR has. One of the standards for that, goes back over half a century, would scale out at about 34m radius. If you want to keep things in proportion to track gauge, you'd use a 45m radius with SLRR track. (I just looked this up.)

Why they adopted that Broad Gauge standard, I have no idea. It's even more exaggerated than what they did with the classic Avatar design.

 

Link to comment
Share on other sites

What I have found so far:

The standard VRC train script uses the the llSensor function to call the llDetectedPos function. This returns a vector value which is the regional coordinates of the target. This code can be put in a child prim: see the llSensor page. Key quote follows:

Sensors placed in prims other than the root prim of an attachment will have their forward direction offset relative to the root prim's forward direction, e.g. a sensor in a prim whose +X direction is the reverse of the root +X will look backward.

The earliest collision-based scripting for trains appears to be obsolete, but the change is not well-documented in the script. I have already done a small rant on that and I shall only refer reader's to Knuth's Literate Programming.

A code fragment is here:

    {
        llSleep(0.5);
        llSensor(gsSensorTargetName, "", ACTIVE | PASSIVE,
            gfSensorSeekRange, gfSensorScanArc);
    }

This is using one of several naming conventions too-briefly documented in the LSL Style Guide which we're expected to recognise instantly. It's a form of Hungarian notation. For a child prim, the sensor scan arc will be affected by the prim's local rotation. There doesn't seem to be any reason to make this different to the root prim.

Thought experiment here: a bogie coach. Even on branch lines, these could be 70ft long, which in proportion to track gauge would be 30m for the SLRR. The root prim is the lead bogie (at the front) while the child (sensor) is the trailing bogie. That gives us two position vectors and two rotations for the nearest "Guide" prims. The arithmetic mean of the two position vectors should be right for the position correction. The VRC code already uses gvUnitToGuideOffset added to the llDetectedPos() so we need a value for the complete coach.

This may be easier if both sensors/bogies are child prims and the root prim is the coach. There may need to be a GuideOffset for each bogie prim.

So the centre of the coach is, in plan or elevation, at the mid-point of a line connecting the sensor/bogie prims, which is where it should be. But what about rotation? Do we just take the mean of the rotations returned by llDetectedRot for the two sensor/bogie prims? It makes sense.

Obviously, passing the data between the various scripts is a complication. But I have been thinking about the real-world item, and how you can model it for SL, and fitting the scripting to that. It doesn't look all that complicated. For something like this it should be fine. (That Railcar entered service in 1934 with skirts over the bogies.)

I do wonder if some of you LSL experts aren't looking at the whole problem. "Literate Programming" again: where's the starting specification in the documentation we see?

2034166600_GWR_railcar_at_York_Aug_17_800x600.jpg.62ed71d7e2ebd8b178c6eb9847317904.jpg

Link to comment
Share on other sites

1 hour ago, arabellajones said:

So the centre of the coach is, in plan or elevation, at the mid-point of a line connecting the sensor/bogie prims, which is where it should be. But what about rotation? Do we just take the mean of the rotations returned by llDetectedRot for the two sensor/bogie prims? It makes sense.

The train simulators such as MSTS and Trainz take the bogie positions as those which should adhere to the track vectors. The hierarchy of objects is a little complex, especially as each simulator uses a different format, but essentially the bogies belong to the parent, in this case the railcar, but in determining the placement of the railcar on the track, it is the bogies that are used.

A complication with any system you try and implement in SL is that you have to cater for reverse-curves, ie the two bogies at their separation are going to have to adopt different rotations to each other. When traversing a crossover, for example the lead bogie will be at an almost opposite angle from the centre-line of the railcar to the trailing bogie. This gives a problem when taking the body as the master object which senses the track and communicates position and rotation information to the child bogies.

If you decided to make the two bogies and the railcar body as three distinct objects you could then have each bogie sensing the track to determine their alignment and communicating their results to the body, effectively telling it where it should go, but that creates more problems : a vector has to be established between the two bogie centres and the body must be aligned along that vector.

Trying to do it with the railcar as a single object would involve some complex puppeteering of the child prims making up the bogies.

 

Edited by Profaitchikenz Haiku
Link to comment
Share on other sites

There's no real hierarchy of the prims in an SL linkset, so that's a bit of a red herring. So it might be necessary to take the position difference between the two sensor prims (a vector) and convert that to a rotation. You picked out an example I missed, thanks.

We have two Guide-prim positions, and the average sets the position of the linkset-root. Those two positions also give us a vector which defines a direction, and we have to rotate the linkset to match that. We have a function to convert a Euler to a Rotation, but how do we get the Euler?

Just running an llSensor/llDetectedRot from the rear bogie isn't going to work because we need to change the rotation to get the value we need.

And, O botheration, this guide-prim vector doesn't always tell you much about the movement of the vehicle. We want the correct distance from the previous vehicle location

Link to comment
Share on other sites

Now, how do we notate this to be clear? Some people do seem to delight in making this complicated...

We start at position Pos₁ and rotation Rot₁ and move a distance Delta. We then do the llSensor routines for the Bogie prims to get the new centreline for the Coach. We're on Vec₁ and we have a Vec₂ defined, and the lines should intersect at Pos₃. Some scripts call it an "Orbit", a rotation around an arbitrary axis. Is an Orbit around Pos₃ with the change of Coach-axis from Rot₁ to Rot₂ going to be a good enough result? Do we need to set a maximum distance to Pos₃

Let's check a couple of standards. The European Berne Gauge specifies 4m centre to centre, which is about 5.45m for SLRR track The SLRR loading gauge is 4m, compared to 3.15m EBG, which would allow 5m centre-to-centre, so maybe the SLRR loading gauge is a bit narrower. Anyway, if the train somehow jumps sideways from one track to another, call it 5m. If the parallel tracks are assumed to converge 250m away, that's 5/250 radians. which is about 1 degree, and that's a pretty small rotation, just do a sideways translation.

Think about this. We have a triangle. Does the difference between a right-angle triangle and an isosceles triangle matter? The Orbit method uses an isosceles triangle. We need to find the distance for the sidestep, but will the difference between sidestep-first and rotation-first matter?

From the SLRR standards, a maximum curve rate of 15 degrees in 5m. That's about 0.25 radians in 5m, 0.05 rad/m, well below the point where the difference between a curve and a straight line matters. This is the Small-angle approximation.

I am now wondering if I was looking the the VRC script for the wrong functions...

If we can use

 {\displaystyle {\begin{aligned}\sin \theta &\approx \theta \\\cos \theta &\approx 1-{\frac {\theta ^{2}}{2}}\\\tan \theta &\approx \theta ,\end{aligned}}}

Some of the rather scary-looking combinations of trig functions are suddenly a lot simpler.

I had better remember to put this in my comments when I turn in my code.

  • Like 1
Link to comment
Share on other sites

You are about to reply to a thread that has been inactive for 1489 days.

Please take a moment to consider if this thread is worth bumping.

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
 Share

×
×
  • Create New...