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

Motorjoint anchors incorrect after resaving with b2dJson

Post by Voptiplex »

Hi Chris,

I do have a problem with saving my world into a JSON file in C++.
Basically, the problem is that in the saved JSON the anchors of a motor joint are not in the location as set in RUBE, but on the local center of the attached bodies.

Have a look at these screenshots:
1. Design in Rube:
1. Design in Rube:
1. Design in Rube:
Screen Shot 2015-02-27 at 15.05.34.png (211.61 KiB) Viewed 29764 times
2. Saved JSON file:
2. Saved JSON file:
2. Saved JSON file:
Screen Shot 2015-02-27 at 15.05.18.png (207.11 KiB) Viewed 29764 times
These are the differentes in the JSON file:
1. Design in Rube:

Code: Select all

		{
			"anchorA" : 
			{
				"x" : 0.01180840004235506,
				"y" : -2.480469942092896
			},
			"anchorB" : 0,
			"bodyA" : 3,
			"bodyB" : 1,
			"correctionFactor" : 0.5,
			"maxForce" : 10,
			"maxTorque" : 10,
			"name" : "MotorJoint",
			"refAngle" : 0,
			"type" : "motor"
		},

Code: Select all

      {
         "anchorA" : 0,
         "anchorB" : 0,
         "bodyA" : 0,
         "bodyB" : 2,
         "maxForce" : "41200000",
         "maxTorque" : "41200000",
         "name" : "MotorJoint",
         "refAngle" : 0,
         "type" : "motor"
      },
As you can see, the the motorjoints are quite different and the saved version does not work.
I can see why the anchors are set like they are, because the local center of the attached bodies is taken.
Why the maxForce and maxTorque do have these values, I do not know.

I have attached the Rube file for you to test.
The design is quite Esels and just for trying the Motor joint.

Could you advise how to get around the problem of the wrong motorJoint ?

Thanks for your help,
Thomas
Attachments
ProofMotorJoint.rube
Rube test file
(7.12 KiB) Downloaded 958 times
Last edited by Voptiplex on Sun Mar 01, 2015 6:16 pm, edited 1 time in total.
iforce2d
Site Admin
Posts: 861
Joined: Sat Dec 22, 2012 7:20 pm

Re: Motorjoint anchors when saving JSON noch

Post by iforce2d »

That's how motor joints work - they depart from the standard use of anchors that all the other joints have. The local anchor for body B is always taken to be (0,0) in that body's coordinates (that's why it is grayed out in RUBE and you cannot alter it). For body A though, the anchor position is relevant and you should be able to set it and export it ok.

The value "41200000" is the hexadecimal representation of the 32bit floating point value for 10. This is probably because you have "Use human-readable floats in JSON" unchecked in the scene settings dialog (export options tab). The purpose of this is to perfectly preserve the floating point value, but in many cases it seems not to be a big deal. If you prefer to use ascii format you can check that checkbox. You can find more info in the built-in help, under "Exporting scenes" -> "Export options"
Voptiplex
Posts: 35
Joined: Thu Nov 14, 2013 1:07 pm

Re: Motorjoint anchors when saving JSON noch

Post by Voptiplex »

Hi Chris,

I am not sure I do understand correctly.
I do get that anchorB is always at local 0,0 of the relevant body.
But anchorA should not be 0, but it is.

a)
I have tried loading one of your example files (jointTypes.json) and then saved the world into
another JSON file.
(jointTypes.rube has got a motorJoint.)
I do get the same problem as in my last test, that anchor A is not correct (it is 0) and the joint is not functional.

b)
Then I copied the original anchorA into the saved rube file by hand and the joint was still not working.
I had to copy the "correctionFactor" : 0.2, as well.
Then the joint work correctly.

Code: Select all

Original RUBE:
{
  "anchorA" : 
  {
    "x" : 5.073556900024414,
    "y" : 5.295198440551758
  },
  "anchorB" : 0,
  "bodyA" : 5,
  "bodyB" : 24,
  "collideConnected" : true,
  "correctionFactor" : 0.2000000029802322,
  "id" : 17,
  "maxForce" : 5.0,
  "maxTorque" : 1,
  "name" : "joint7",
  "referenceAngle" : 0,
  "type" : "motor"
},


Saved Json:
{
   "anchorA" : 0,
   "anchorB" : 0,
   "bodyA" : 15,
   "bodyB" : 19,
   "collideConnected" : true,
   "maxForce" : "40A00000",
   "maxTorque" : 1,
   "name" : "joint7",
   "refAngle" : 0,
   "type" : "motor"
},


Could you explain the issue a bit more as I am missing something important here ?

Cheers,
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 »

Can you tell me what version of RUBE you are using, and what OS you are running on?

Yes, you had explained it ok I think. It's just that when I opened your file and exported, the anchor A position was exported correctly (as below) so I thought perhaps you had just mistaken or mis-pasted the output or something. The issue with anchor B of motor joints was also clouding the issue for me, sorry :)

Code: Select all

		{
			"anchorA" : 
			{
				"x" : 0.01180840004235506,
				"y" : -2.480469942092896
			},
			"anchorB" : 0,
			"bodyA" : 3,
			"bodyB" : 1,
			"correctionFactor" : 0.5,
			"maxForce" : 10,
			"maxTorque" : 10,
			"name" : "MotorJoint",
			"refAngle" : 0,
			"type" : "motor"
		},
Can you define what you mean by "working" in the b) paragraph? You mean the joint parameters were applied as expected when opening the file, or the joint actually functioned correctly in the player view, or the values were then exported as non-zero in the .json output, or all of these, or.... something else?
iforce2d
Site Admin
Posts: 861
Joined: Sat Dec 22, 2012 7:20 pm

Re: Motorjoint anchors when saving JSON not ok.

Post by iforce2d »

ah, looks like you are on Mac, with the latest version. I'll take a look on Mac and see what happens.
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 using RUBE 1.6.1 on Mac OSX with JSON loader 02.12.2013.

I am a bit puzzled that your exported file contains the "correctionFactor" : 0.5,
as my b2dJson.cpp contains the following code and correctionFactor should not be set:

Code: Select all

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

        b2MotorJoint* motorJoint = (b2MotorJoint*)joint;
        vecToJson("anchorA", bodyA->GetLocalPoint(motorJoint->GetAnchorA()), jointValue);
        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);
    }

With a working motorJoint I mean, that in the playerView the joint moves the body as expected AFTER I copied both the
anchorA and the correction factor by hand.
(In the example jointTypes the body is placed left of the motorJoint and gets pulled towards the joint and can be moved afterwards.)

With the unchanged saved JSON file, the motorJoint does not seem to do anything. The body moves, but does not get pulled towards the expected
joint position.
(I have not tried with just the correction factor without anchorA.)

The parameters do look OK in the RUBE editor apart of missing correction factor.


I will attach the saved JSON for you to try and copy the two parameters into the file.

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

Re: Motorjoint anchors when saving JSON not ok.

Post by Voptiplex »

Mmmhhh, I am not allowed to attach JSON files ... .
iforce2d
Site Admin
Posts: 861
Joined: Sat Dec 22, 2012 7:20 pm

Re: Motorjoint anchors when saving JSON not ok.

Post by iforce2d »

ah, thanks for pointing out that commented line in b2dJson.cpp
I think that was originally commented because the GetCorrectionFactor was not part of the Box2D API way back when that code was originally written (http://code.google.com/p/box2d/issues/detail?id=302), and then I forgot to update the github after it was added.

I've added .json to the accepted attachments list (.txt or .zip should work too). Then again, I don't really know how it will help to find a problem in RUBE, by looking at a file that you have edited by hand :)
Voptiplex
Posts: 35
Joined: Thu Nov 14, 2013 1:07 pm

Re: Motorjoint anchors when saving JSON not ok.

Post by Voptiplex »

Hi Chris,

for what it is worth, I have attached the file saved with b2djson.
The jointTypes example file saved in original version, the saved file changed by hand.

Then i have uncommented the correctionFactor in b2dJson and tried again.
As expected, the anchorA is still wrong, but the motorJoint is funktional now.

Regards,
Thomas
Attachments
jointTypes_Saved_EnabledCorrectionFactor.json
Saved file, but with corrFactor uncommented in b2djson
(44.44 KiB) Downloaded 952 times
jointTypes_Saved_ChangedByHand.json
The saved file, but corrFactor and anchorA edited by hand
(43.5 KiB) Downloaded 950 times
jointTypes_Saved.json
jointTypes_Saved
(44.4 KiB) Downloaded 955 times
iforce2d
Site Admin
Posts: 861
Joined: Sat Dec 22, 2012 7:20 pm

Re: Motorjoint anchors when saving JSON not ok.

Post by iforce2d »

Wait a minute....
Are we talking about a .json that you get by exporting from RUBE, or a .json you get by exporting from your own program, using the b2dJson class? In the .json files you attached, there are comments like
//dynamic
for the body types, which must be coming from the b2dJson from github, not from RUBE right? (I removed those from RUBE's output because it's not valid JSON, although many parsers will ignore it).

If we are talking about your own program, then I am confused about the point of the screenshots in your first post.... did you create the scene in RUBE and then export, load it into your program, and then export it again via the b2dJson or something? hmm... if this is what you are talking about, then I think the bug may be that the linearOffset property is not being output by RUBE. Looking at the RUBE source code, I see that for some reason I have made it use the anchor A as the linear offset. Here is my constructor for b2MotorJoint.cpp:

Code: Select all

b2MotorJoint::b2MotorJoint(const b2MotorJointDef* def)
: b2Joint(def)
{
    //m_linearOffset = def->linearOffset;  <--- commented this out
    m_localAnchorA = def->localAnchorA;
    m_localAnchorB = def->localAnchorB;
    m_linearOffset = m_localAnchorA;  <--- added this
    m_angularOffset = def->angularOffset;

    m_linearImpulse.SetZero();
    m_angularImpulse = 0.0f;

    m_maxForce = def->maxForce;
    m_maxTorque = def->maxTorque;
    m_correctionFactor = def->correctionFactor;
}
I think the point of this was to standardize all joints to use similar anchor A/B style GUI inputs any symbols, and the same manipulation by mouse, instead of having just one joint being the odd-one-out and having grayed-out values for both anchors. After all, the linear offset has the same effect as anchor A anyway. But the problem is, this value is not being output, so while RUBE will read it in correctly, other programs will not.

As a simple check, you could try changing the same two lines as I have done in your own Box2D source code.

No... wait... in the b2dJson where motor joints are parsed, the anchor A is already being used as the linearOffset:

Code: Select all

motorDef.linearOffset = jsonToVec("anchorA", jointValue);//editor uses anchorA as the linear offset
So now I'm confused again :D
Post Reply