Measuring axis rotation relative to a prop?

After a year of Garrys mod celibate, I’ve decided to begin playing again. My wiremod and building skills have gotten a little rusty, so I need a little help

I need to figure out how to measure an axis rotation angle (0-360) relative to the prop that it is attached to. This is useful for multiple engine and robot applications.
This basically means I cant just use a regular gyroscope, because it outputs the pitch yaw roll angle relative to the world. It will work if I keep the axis stationary, but if I rotate the base (pitch or roll) it won.t work anymore.

It has to be able to work in high-speed applications.

Thanks.

Dunno about hi-speed, but…
Im assuming that you want to be able to check for instance the angle of a joint, right? You could simply get the angles for both props and subtract one from the other. Then you should have their “angular offset”. If everything is nice and straight you should get only one angle that is greater than zero.

That really doesn’t work either. Any more suggestions?

Could you be more specific somehow? I am not sure that i understand your question.

Yeah I knew that was coming. When I keep my axel still and it is spinning in yaw (Z-axel), it works like a charm.
But lets say I rotate the whole system 90 degrees in roll or pitch axel (Y or X). Now even when the plate is spinning in the same direction relative to the base, the gyroscope now only outputs the rotational shift in pitch or roll axel.
And the weirdest thing is that if I rotate the base only 45 degrees, it outputs a little of both axels.

I think I’m going to try it with 3 gps chips.
GPS A will be on the base, above the axel.
GPS B will be in the middle of the axel
GPS C will be on the edge of the spinning plate.

The angle between vector AB and BC will give me the rotational shift. Though I got to find a way to make a difference between the two sides, as this will only output the smallest angle.

I think i am starting to understand what you are aiming at. Does this give an accurate description of what you are trying to achieve

Say you have a robot with a leg. You want it to stand in a position that makes the angle of the joint be 160 degrees (slightly bent). You want to get the angular offset, whatever the individual components rotation in the world is.

He gps system could work, though i recommend using either e2 or entity gates to get the position of the components directly (more precise). You can find out the lenght of the vector between the two and tye distance between them and the actual axis point (if its welded properly it should be a point in between the limb’s two coordinates). This forms a triangle, of which you know all sides, making it easy to calculate the wanted angle.

Yeah, i reallise that i am suggesting he same thing as you just said, but i do recommend you to use entity or expression 2, not gps’s.

That was actually one the uses. But when I made this thread I began working on a small 8-piston radial engine.

I am not familiar with E2 or entities, but I quess I got to try to learn them.

Entity chips are super-usefull. I wrote the wiki article just the other day. Link

Surprisingly, I made just the thing for this using the same sort of GPS coordinate setup that you were referring to - except it’s all done inside of an e2 instead. Was going to make a different walking setup with it, but I ended up not caring.

Chip doesn’t care what the orientation of your wheel is, it’ll try to “pitch” it from 0 to 360 using applyTorque.



@name Motor
@inputs [Motor]:entity Target Active
@outputs Pot Offset
@persist [DMF DMU Motf Motu]:vector
@persist Af Au Offset Offint Damp
#tweaks
@persist Fam P I D
@trigger 

interval(10)

if(first() | dupefinished())
{
    #Motor forward/Motor Up
    DMF = Motor:toLocal(Motor:pos() + entity():forward() * 200)
    DMU = Motor:toLocal(Motor:pos() + entity():up() * 200)
    Fam = 5000 # Force amount
    
    P = 1 # Proportional Amount
    I = 0 # Integral Amount
    D = 5 # Derivative Amount
}

Motf = (Motor:toWorld(DMF) - Motor:pos()):normalized()
Motu = (Motor:toWorld(DMU) - Motor:pos()):normalized()

Af = acos(clamp(Motf:dot(entity():up()), -1, 1))
Au = acos(clamp(Motu:dot(entity():up()), -1, 1))

Pot = Au * (Af >= 90) + (360 - Au) * (Af < 90)

Offset = angnorm((Target % 360) - Pot)

if(!(Motor:isFrozen()) & Active)
{
    Offint += Offset * 0.01
}
else
{
    Offint = 0
}
Damp = angnorm($Pot * -1)

Motor:applyTorque(Active * (P * Offset + I * Offint + D * Damp) * entity():right() * -Fam * Motor:inertia())


Thats great! But how do I actually use that? I mean how do I give it the inputs.

Place the chip on the main body of your contraption facing “forward”, link the motor entity to an entity marker, and give it an input. It should rotate.

You have 4 variables you can tweak - Fam for the force amount multiplier, and the PID loop. If you just want it to output relative angle differences so you can do your own force setup, you can set Fam to 0, and read the outputs Pot (0-360 relative to the chip’s “up” direction) and Offset (-180 to 180 relative to the chip’s “up” direction) to do whatever stuff you need it to do.

Ha, just kidding, the applyTorque setup for this flips rotation if you yaw it beyond -180 to 180. The Pot, Damp, and Offint values are fine, it’s just applytorque fucking up.



@name Latch/Motor
@inputs [Motor]:entity Target Active
@outputs Pot Offset FAMT Debug:vector
@persist [DMF DMU Motf Motu]:vector
@persist Af Au Offset Offint Damp TVar
#tweaks
@persist Fam P I D
@trigger 

interval(10)

if(first() | dupefinished())
{
    #Motor forward/Motor Up
    DMF = Motor:toLocal(Motor:pos() + entity():forward() * 200)
    DMU = Motor:toLocal(Motor:pos() + entity():up() * 200)
    Fam = 1 # Force amount
    
    P = 1 # Proportional Amount
    I = 0 # Integral Amount
    D = 5 # Derivative Amount
}

Motf = (Motor:toWorld(DMF) - Motor:pos()):normalized()
Motu = (Motor:toWorld(DMU) - Motor:pos()):normalized()

Af = acos(clamp(Motf:dot(entity():up()), -1, 1))
Au = acos(clamp(Motu:dot(entity():up()), -1, 1))

Pot = Au * (Af >= 90) + (360 - Au) * (Af < 90)

Offset = angnorm((Target % 360) - Pot)

if(!(Motor:isFrozen()) & Active)
{
    Offint += Offset * 0.01
}
else
{
    Offint = 0
}

Damp = angnorm($Pot * -1)

Motor:applyOffsetForce(Active * (P * Offset + I * Offint + D * Damp) * -Fam * entity():up() * Motor:mass(), Motor:massCenter() + entity():forward() * 100)
Motor:applyOffsetForce(Active * (P * Offset + I * Offint + D * Damp) * Fam * entity():up() * Motor:mass(), Motor:massCenter() - entity():forward() * 100)

Debug = Motf

FAMT = P * Offset + I * Offint + D * Damp

Debug = vec(Offset, Offint, Damp)


This’ll work as intended with respect to the actual rotational motion.