chrono
chrono copied to clipboard
SIGSEGV on ChContactContainerNSC::AddContact in C#
Windows 10 chrono 6.0.0@master Unity 2019.3.10f1
I am attempting to use chrono in Unity3d, with the csharp bindings. All is going as expected, except when a body collides with another body, Unity crashes. Opening the crash.dmp file, I found the error messages which was:
The thread tried to read from or write to a virtual address for which it does not have the appropriate access.
And the end of the stack trace is:
========== OUTPUTTING STACK TRACE ==================
0x00007FF84C6F3618 (ChronoEngine) chrono::ChContactContainerNSC::AddContact
0x00007FF84C97ECB6 (ChronoEngine) chrono::collision::ChCollisionSystemBullet::ReportContacts
0x00007FF84C6B3438 (ChronoEngine) chrono::ChSystem::ComputeCollisions
0x00007FF84C6B5EA9 (ChronoEngine) chrono::ChSystem::Integrate_Y
0x00007FF84C6B4600 (ChronoEngine) chrono::ChSystem::DoStepDynamics
0x00007FF855AC977B (ChronoEngine_csharp_core) CSharp_ChSystem_DoStepDynamics
....
My Unity C# code looks like this: ChBody wrapper:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ChronoBody : MonoBehaviour
{
ChBody body;
public float mass = 1;
public bool isStatic = false;
public int indentity = 0;
private void Awake()
{
ChSystemNSC ch_system = ChronoSystem.Instance.system;
body = new ChBodyEasyBox(1,1,1,0.5,false,true);
body.SetPos(transform.position.toChV());
ch_system.Add(body);
}
private void FixedUpdate()
{
ChVectorD vec = body.GetPos();
transform.position = body.GetPos().toVec3();
transform.rotation = body.GetRot().toQuat();
if (isStatic)
body.SetNoSpeedNoAcceleration(); //TEMP for testing
}
}
ChSystem:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ChronoSystem : MonoBehaviour
{
public int SolverMaxIterations = 20;
private static ChronoSystem _instance;
public static ChronoSystem Instance { get { return _instance; } }
public ChSystemNSC system;
MyReportContactCallback callback;
private void Awake()
{
if (_instance != null && _instance != this)
{
Destroy(this.gameObject);
}
else
{
_instance = this;
}
system = new ChSystemNSC();
system.SetSolverMaxIterations(Instance.SolverMaxIterations);
system.SetChTime(0);
ChCollisionModel.SetDefaultSuggestedEnvelope(0.001);
ChCollisionModel.SetDefaultSuggestedMargin(0.001);
}
private void FixedUpdate()
{
system.DoStepDynamics(Time.fixedDeltaTime);
}
}
Here are all the log files associated with the crash: https://drive.google.com/drive/folders/1P8S5tZOczySgISrKqK1j_P0dy8rPubQO?usp=sharing
Any help, or just a hint in the right direction would be much appreciated.
I just started with the chrono & unity and encountered the same problem.
Sorry, the original issue by @AFIDclan slipped through the cracks.
Just looking at the code he/she posted, I see an issue where a ChBodyEasyBox is constructed requesting a collision shape be generated, but no contact material is provided. There is a debug assertion for this in the constructor, but no check in release.
@BenjaminYde do you have similar code?
@rserban, thanks for the fast reply!
After some try outs I got it working. In the following example some code:
public class ChronoSimulation : MonoBehaviour
{
// .. FIELDS
private ChSystemNSC system = null;
private ChBody bodyBoxGround = null;
private ChBody bodyBoxFalling = null;
// .. INITIALIZATION
void Start()
{
system = new ChSystemNSC();
system.SetChTime(0);
var boxMaterial = new ChMaterialSurfaceNSC();
boxMaterial.SetFriction(0.3f);
boxMaterial.SetCompliance(0);
// following version is NOT working!
/*bodyBoxGround = new ChBodyEasyBox(10,0.5,10,1);
bodyBoxGround.SetBodyFixed(true);
bodyBoxGround.SetPos(new ChVectorD(0, 0, 0));
bodyBoxGround.SetCollide(true);
system.AddBody(bodyBoxGround);
bodyBoxFalling = new ChBodyEasyBox(1,1,1,1);
bodyBoxFalling.SetPos(new ChVectorD(0,3,0));
bodyBoxFalling.SetCollide(true);
system.AddBody(bodyBoxFalling);*/
// following version is working!
bodyBoxGround = new ChBodyEasyBox(10,0.5,10,1, boxMaterial, ChCollisionSystemType.CHRONO);
bodyBoxGround.SetBodyFixed(true);
bodyBoxGround.SetPos(new ChVectorD(0, 0, 0));
bodyBoxGround.SetCollide(true);
system.AddBody(bodyBoxGround);
bodyBoxFalling = new ChBodyEasyBox(1,1,1,1, boxMaterial, ChCollisionSystemType.CHRONO);
bodyBoxFalling.SetPos(new ChVectorD(0,3,0));
bodyBoxFalling.SetCollide(true);
system.AddBody(bodyBoxFalling);
// following version is working!
/*bodyBoxGround = new ChBody();
bodyBoxGround.GetCollisionModel().AddBox(boxMaterial, 10,0.25,10);
bodyBoxGround.SetBodyFixed(true);
bodyBoxGround.SetPos(new ChVectorD(0, 0, 0));
bodyBoxGround.SetCollide(true);
system.AddBody(bodyBoxGround);
bodyBoxFalling = new ChBody();
bodyBoxFalling.GetCollisionModel().AddBox(boxMaterial, 0.5,0.5,0.5);
bodyBoxFalling.SetPos(new ChVectorD(0,3,0));
bodyBoxFalling.SetCollide(true);
system.AddBody(bodyBoxFalling);*/
}
// .. UPDATE
private void FixedUpdate()
{
system.DoStepDynamics(0.01);
}
// .. DEBUG
private void OnDrawGizmos()
{
if (!Application.isPlaying)
return;
// ground
ChVectorD chPosGround = bodyBoxGround.GetPos();
Vector3 posGround = new Vector3((float)chPosGround.x, (float)chPosGround.y, (float)chPosGround.z);
Gizmos.DrawCube(posGround, new Vector3(10,0.5f,10));
// falling box
ChVectorD chPosBoxFalling = bodyBoxFalling.GetPos();
Vector3 posBoxFalling = new Vector3((float)chPosBoxFalling.x, (float)chPosBoxFalling.y, (float)chPosBoxFalling.z);
Gizmos.color = Color.red;
Gizmos.DrawCube(posBoxFalling, Vector3.one);
}
}
I assume that in the version you commented as "not working" you do not get collisions, correct?
That is because you create the bodies without collision shapes. See the C++ documentation for ChBodyEasyBox
: by default, such a body is constructed with visualization shapes but not collision shapes. Try using either
bodyBoxFalling = new ChBodyEasyBox(1, 1, 1, 1, true, true, boxMaterial)
or
bodyBoxFalling = new ChBodyEasyBox(1, 1, 1, 1, false, true, boxMaterial)
depending on whether or not you want to create the underlying Chrono visualization asset.
Note also that your second version (the uncommented "working" one) uses a different collision system. There are two options in Chrono, the default one based on Bullet and a Chrono internal one. The two types are specified with ChCollisionSystemType.BULLET
and ChCollisionSystemType.CHRONO
, respectively., See the ChangeLog entry.
Finally, your third version (the commented "working" one) uses the default Bullet-based collision system, but a default body mass of 1, which is different from the mass you end up with when using ChBodyEasyBox
(10).
To make a long story short, all 3 versions will work, but you must be careful in setting parameters to make them equivalent. Consult the documentation for details.
Thanks for the clarification! I just started with chrono and these tips will certainly help!