Motorjoint anchors incorrect after resaving with b2dJson

Report problems here (or use the built-in feedback dialog in the editor)
Voptiplex
Posts: 35
Joined: Thu Nov 14, 2013 1:07 pm

Re: Motorjoint anchors when saving JSON not ok.

Post by Voptiplex »

Hi Chris,
yes, I am designing inside Rube, generate the JSON file in Rube,
load the JSON file into my App and then let the App save the changed world to JSON again.
And in the JSON saved by my App the error occurs.
Sorry if I was not explicit enough in my problem description.

My code does contain your snippet:

Code: Select all

motorDef.linearOffset = jsonToVec("anchorA", jointValue);//editor uses anchorA as the linear offset
but my motorJoint declaration does look different, because I do not have
m_localAnchorA and m_localAnchorB !?!?!
So I can not try your changes ..... .

This is my b2MotorJoint declaration:

Code: Select all

class b2MotorJoint : public b2Joint
{
public:
    b2Vec2 GetAnchorA() const;
    b2Vec2 GetAnchorB() const;

    b2Vec2 GetReactionForce(float32 inv_dt) const;
    float32 GetReactionTorque(float32 inv_dt) const;

    /// Set/get the target linear offset, in frame A, in meters.
    void SetLinearOffset(const b2Vec2& linearOffset);
    const b2Vec2& GetLinearOffset() const;

    /// Set/get the target angular offset, in radians.
    void SetAngularOffset(float32 angularOffset);
    float32 GetAngularOffset() const;

    /// Set the maximum friction force in N.
    void SetMaxForce(float32 force);

    /// Get the maximum friction force in N.
    float32 GetMaxForce() const;

    /// Set the maximum friction torque in N*m.
    void SetMaxTorque(float32 torque);

    /// Get the maximum friction torque in N*m.
    float32 GetMaxTorque() const;

    /// Set the position correction factor in the range [0,1].
    void SetCorrectionFactor(float32 factor);

    /// Get the position correction factor in the range [0,1].
    float32 GetCorrectionFactor() const;

    /// Dump to b2Log
    void Dump();

protected:

    friend class b2Joint;

    b2MotorJoint(const b2MotorJointDef* def);

    void InitVelocityConstraints(const b2SolverData& data);
    void SolveVelocityConstraints(const b2SolverData& data);
    bool SolvePositionConstraints(const b2SolverData& data);

    // Solver shared
    b2Vec2 m_linearOffset;
    float32 m_angularOffset;
    b2Vec2 m_linearImpulse;
    float32 m_angularImpulse;
    float32 m_maxForce;
    float32 m_maxTorque;
    float32 m_correctionFactor;

    // Solver temp
    int32 m_indexA;
    int32 m_indexB;
    b2Vec2 m_rA;
    b2Vec2 m_rB;
    b2Vec2 m_localCenterA;
    b2Vec2 m_localCenterB;
    b2Vec2 m_linearError;
    float32 m_angularError;
    float32 m_invMassA;
    float32 m_invMassB;
    float32 m_invIA;
    float32 m_invIB;
    b2Mat22 m_linearMass;
    float32 m_angularMass;
};

Did you do any changes to the Box2D code ?
Version 2.2.1 did not contain the motorJoint, so I assume you are using a later version ?

I am using version 2.3.1 from here:
http://box2d.org/2014/04/box2d-v2-3-1-released/

Now I am confused as well.

Best regards,
Thomas
iforce2d
Site Admin
Posts: 861
Joined: Sat Dec 22, 2012 7:20 pm

Re: Motorjoint anchors when saving JSON not ok.

Post by iforce2d »

yes, I am designing inside Rube, generate the JSON file in Rube,
load the JSON file into my App and then let the App save the changed world to JSON again.
ok, finally we are on the same page :D So the fact that you originally exported from RUBE, and the version and OS etc is irrelevant. Can I ask why you're doing this double export?
This is my b2MotorJoint declaration:
The code I gave is for the constructor of b2MotorJoint, not the declaration.
I do not have m_localAnchorA and m_localAnchorB !?!?!
I'm pretty sure if you look closely, they are in the code you pasted there.
iforce2d
Site Admin
Posts: 861
Joined: Sat Dec 22, 2012 7:20 pm

Re: Motorjoint anchors when saving JSON not ok.

Post by iforce2d »

iforce2d wrote:
I do not have m_localAnchorA and m_localAnchorB !?!?!
I'm pretty sure if you look closely, they are in the code you pasted there.
I'm sorry, sometimes I hit post too quickly. They are not in the code you pasted, they are in the b2Joint superclass. Did it fail to compile?
Voptiplex
Posts: 35
Joined: Thu Nov 14, 2013 1:07 pm

Re: Motorjoint anchors when saving JSON not ok.

Post by Voptiplex »

Hi Chris,

I am sorry, but I can not follow you.
When I change the motorJoint as you have suggested, the code does not compile.
I can not find m_localAnchorA/m_localAnchorB in any b2Joint superclass for Box2D version v2.2.1, v.2.3.0, v.2.3.1.
A few joints like weld joint, rope joint etc. do have m_localAnchorX, but other joints like the motor joint do not.

The motorJointDef as used in your code changes does also not contain m_localAnchorX.
m_localAnchorA = def->localAnchorA;

Code: Select all

/// Motor joint definition.
struct b2MotorJointDef : public b2JointDef
{
    b2MotorJointDef()
    {
        type = e_motorJoint;
        linearOffset.SetZero();
        angularOffset = 0.0f;
        maxForce = 1.0f;
        maxTorque = 1.0f;
        correctionFactor = 0.3f;
    }

    /// Initialize the bodies and offsets using the current transforms.
    void Initialize(b2Body* bodyA, b2Body* bodyB);

    /// Position of bodyB minus the position of bodyA, in bodyA's frame, in meters.
    b2Vec2 linearOffset;

    /// The bodyB angle minus bodyA angle in radians.
    float32 angularOffset;
    
    /// The maximum motor force in N.
    float32 maxForce;

    /// The maximum motor torque in N-m.
    float32 maxTorque;

    /// Position correction factor in the range [0,1].
    float32 correctionFactor;
};
It does look like you have a different version of Box2D or you have some special changes.
Could you just compare a release version motorjoint.h/.c with your code, please ?

Thanks,
Thomas
Voptiplex
Posts: 35
Joined: Thu Nov 14, 2013 1:07 pm

Re: Motorjoint anchors when saving JSON not ok.

Post by Voptiplex »

Hi Chris,

I think I found the solution. You triggered the idea with your anchorA to LinearOffset.
So to fix my problem I needed to save linearOffset into the JSON anchorA (in the file b2dJson.cpp).

Code: Select all

    case e_motorJoint:
        {
            jointValue["type"] = "motor";

            b2MotorJoint* motorJoint = (b2MotorJoint*)joint;
            // vecToJson("anchorA", bodyA->GetLocalPoint(motorJoint->GetAnchorA()), jointValue); // <--original
            vecToJson("anchorA", motorJoint->GetLinearOffset(), jointValue); // <--changed

            vecToJson("anchorB", bodyB->GetLocalPoint(motorJoint->GetAnchorB()), jointValue);
            floatToJson("refAngle", motorJoint->GetAngularOffset(), jointValue);
            floatToJson("maxForce", motorJoint->GetMaxForce(), jointValue);
            floatToJson("maxTorque", motorJoint->GetMaxTorque(), jointValue);
            floatToJson("correctionFactor", motorJoint->GetCorrectionFactor(), jointValue);
        }
        break;
Will do more tests with the changes.

Cheers,
Thomas
iforce2d
Site Admin
Posts: 861
Joined: Sat Dec 22, 2012 7:20 pm

Re: Motorjoint anchors incorrect after resaving with b2dJson

Post by iforce2d »

Yes, you are correct. Sorry I had not much time to look at this in detail (eg. compile and run all this myself) and I started off on the completely wrong path since you gave RUBE screenshots and a RUBE file to check etc. Anyway, I had some more time today and did all the loading and re-saving as you are doing, then made some changes to the b2dJson source which should fix things:
https://github.com/iforce2d/b2dJson/com ... 81d5420c09

I will also modify RUBE so that it does not output the linearOffset into the anchorA value in the exported JSON, because that is confusing and the fact that anchorA is storing the linear offset should only be relevant inside the RUBE GUI anyway.

Can I ask what the goal of your re-saving is? If there is something that the editor could do to help that workflow, it might make things easier for you.
Voptiplex
Posts: 35
Joined: Thu Nov 14, 2013 1:07 pm

Re: Motorjoint anchors incorrect after resaving with b2dJson

Post by Voptiplex »

Hi Chris, sorry for the late reply.

Your patch works well, thanks for that.
I assume with the jointValue.isMember magic, the loader works with current and future releases of RUBE, yes ?

It is kind of hard to get the patch, as you have not merged back your development branch into your main branch on github.

Kind regards,
Thomas
iforce2d
Site Admin
Posts: 861
Joined: Sat Dec 22, 2012 7:20 pm

Re: Motorjoint anchors incorrect after resaving with b2dJson

Post by iforce2d »

Yes, it will handle both cases. It would probably be easiest just to replace your b2dJson files with the current ones, rather than merging anything. I have not made any branches on github that I'm aware of...

Can I ask what the goal of your re-saving is? If there is something that the editor could do to help that workflow, it might make things easier for you.
Voptiplex
Posts: 35
Joined: Thu Nov 14, 2013 1:07 pm

Re: Motorjoint anchors incorrect after resaving with b2dJson

Post by Voptiplex »

Hi, I am not working on a game, rather a simualtion of real world objects.
My app uses joints and bodies to render a geometrical figure onto the screen.

I load the Box2D design from Rube into my App, where the user is encouraged to change the design.
This design is animated with Box2D to be physically correct.
And if the user is happy, he can save his new design and re-load it later or share it with others.

I am not sure if using b2dJson to save the resulting box2D world is the best approach, but now it seems to work fine.
And I can not really see how RUBE could make this workflow easier.

I just wish to have a way to measure length and angle in RUBE, as my objects need to be very precise and accurate to simulate real world objects (Precise compared to a game where the dimensions are not so important.)

You are much more experienced in these issues, do you have any suggestions ?

Thanks,
Thomas
iforce2d
Site Admin
Posts: 861
Joined: Sat Dec 22, 2012 7:20 pm

Re: Motorjoint anchors incorrect after resaving with b2dJson

Post by iforce2d »

I see. In that case yeah, I think that is the best approach. Just keep in mind that the world will not always be a perfect replication of what it was when saved (order of bodies in GetBodyList may be different etc, so collisions are not deterministic between saves). The other thing is if you use the ascii representation of floats, then floats will be a little different when re-loaded.

For measuring length, do you mean a simple tool to check the distance between two points? I will add this sometime, yes. For example, the old version of the editor had that feature: https://www.youtube.com/watch?v=aCHKUT2LST8#t=3m7s
For angles though, I'm not sure exactly what you mean or how it would be implemented. Measuring an angle would require specifying three points right?
Post Reply