-
Notifications
You must be signed in to change notification settings - Fork 885
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adding Force to GameObjects in Unity (using MuJoCo physics) #360
Comments
Take a look at how MjMouseSpring.cs does it, its inside the Editor components folder of the plugin. Basically it's editing a field in the mujoco scene's data structure, something like this:
Where appliedForce is the Mujoco vector representation of your force. You may need to convert it to that format with Alternatively if your cube is just a free body (i.e. has a freejoint) you may also control the appropriate elements of qfrc_applied as well, which may be equivalent in this case. For more info you can check out the docs adressing this: |
Ok. I was looking around MjMouseSpring, MjBody, etc. and was still a little lost (I am very new to MuJoCo so its just a little confusing for me). The goal for what I am doing is to apply a force on the Z axis only to a free body cube. I understand that I would want to do something like
but the problem that I kept running into was that I am trying to do this in a MonoBehavior class but then I kept getting stuck on how to add Thank you in advance. I'm just starting with Mujoco and your help is greatly appreciated. Would something like this work at all or am I just totally lost? |
No problem! In Mujoco there is a slightly different approach to how information about elements in a scene are stored and accessed when compared to how Unity handles it on a surface level. I may go into details that you are already familiar with, but I'd like to mention them just in case. But first to explain how Once you have a GameObject with an MjBody attached, an MjScene will be created at the start of play mode. After that, all information about the Mujoco side of the simulation can be accessed through that MjScene. Instead of each MjBody storing all information about their state themselves, the MjScene keeps track of all bodies' current states, velocities and accelerations on separate arrays. Since, for example, all positions are stored in one array, if you want to find the data of a specific body, you need to know where to start within that array. This address will be different for different arrays, depending on how many array elements there are per body/component. There are different ways to access this address for each array, but it is often Now that you have the address of where your current MjBody's information starts in the xfrc_applied array, you need the array itself. You access it from the MjScene like this:
Behaviours that often need to access the mujoco Data may store the reference to the MjScene like this:
Also don't forget that in Mujoco the order of vector components are different (the Z component is up). Perhaps the best way to get the mujoco force vector that accelerates your object towards the local forward is to use Let me know if anything else is unclear! |
If you frequently have to apply xfrc to MjBodies it might be worth writing an extension method for that. Something like this (untested):
I think quality of life functions like this will eventually be included in the plugin. |
That is very helpful! The only problem that I am running into right now is during runtime, a NullPointerException is thrown, stating that an object reference is not set to an instance of the object. I presume this issue is coming from the |
Thats likely related to the fact that the MjScene initializes on Start() as well. So currently you want to acces the mujoco data before its Start() has been called by Unity. There are a couple ways to adress this. Inside the project settings in Unity, you can define the execution order of different scripts, and can place MjScene at the top. Instead you may also call MjScene.Instance.CreateScene() in your behaviour to make sure the scene is ready to be accessed. You could also set the force in Update(), and skip it once its initialised You may also call a couroutine in start that skips one frame and initializes the force on the next one. These are I think the main ways to guarantee a MjScene being ready. In the future it might be good to maybe have an event after scene creation that scripts could subscribe to on Awake(), or another convenient way to simplify this issue. |
Ok. Is the way I initiated and declared correct (as in setting |
As long as the component is attached to the same gameobject as the behaviour is, then that should give you the reference to it. If its on a different GameObject then you may need to If you double click the error message it should take you to the line it occurs. Alternatively you could also call |
Hi. I'm sorry for the repeated questions. I got it to a point where there are no compiler or runtime issues. I have safeguards to make sure that the scene and the body references are present and attached to the gameObject. When ran, the block that the force should be enacted on is not moving at all, which is strange because I even have 3 lines that are printed to the console that prints the forces enacted on each the x, y, and z axis. Not really sure where my issue is coming from now. LMK if you have any ideas but I greatly appreciate your help.
|
Are you sure that the gameobject has a child gameobject that has a mjfreejoint component? In Mujoco by default bodies are not allowed to move. You need to allow a body degrees of freedom (number of ways it can move in relation to its parent body) by associating a joint with it. Freejoint allows unrestricted movement, which is what you need. If you didnt have a joint, then there is also a chance you dont have an MjGeom either. MjGeom components are the equivalent of colliders in mujoco (+ some extras). That should be attached to another child gameobject (sibling of the joint). That gives you a collider but no rendering. You can right click the geom component and you should see the option to automatically add the corresponding mesh renderer. So it should be:
I recommend importing a complete scene from an xml file and looking how its set up. |
Finally got it to work. I had the MjFreeJoint, MjGeom, and MjMeshFilter. The problem eventually was that it should not have been in |
Hi. I am trying to add a force vector to a cube in Unity, yet to my best knowledge, in order to add a force vector to a GameObject in Unity, the script itself needs a rigidbody. If using MuJoCo physics in Unity, which replaces the need for rigidbodies, how do I add a force vector? The following C# script is how I simply added a force vector to a cube that is not using MuJoCo physics properties and does in fact have a rigidbody.
AddForce
The text was updated successfully, but these errors were encountered: