Page 1 of 1

Rope with heavy rigid body attached

Posted: Mon Aug 15, 2011 1:41 pm
by Thor Erling
I have been working with bullet for a while, it works great except from one important area. We are using bullet for making a realistic offshore crane simulator. An important part of this simulation is hanging heavy load in a wire when a ship is moving. I have tried with generic6dOfConstraint and with soft body rope. I always run into the same problem. With a light rope and a heavy load (RigidBody) the rope acts like rubber. In real life a wire is quite stiff and able to hold heavy load. I have tried a dozen different things, but I have not managed to avoid this problem. We want to model the physics world as accurate as possible, but when it comes to ropes(wires) we are stucked. I have also simular problem using "Open Dynamics Engine". I mean that a physic engine should handle constraint between bodies with large difference in mass and "moment of inertia" in a correct way.
If anyone can help me, I will be very happy.

Re: Rope with heavy rigid body attached

Posted: Tue Aug 16, 2011 9:32 am
by gaston

Don't really know if this helps but...

I had a similar problem and I couldn't find a solution within bullet. To set the linear stiffness to 1.0 is not enough, the rope will still have alot of stretch it seems (somewhat depending on the rope and actors' mass). In order to have a fully stiff rope with no stretch at all I had to add some code to the dynamics that helps the rope to maintain its maximum stretch (a wire would have near zero stretch). What this code does is that it cancels out all velocity on the attached actor(s) as it reaches beyond a certain distance from the rope's other anchor, but only the velocity that points in the direction away from the rope/wire. Velocity towards the rope should not be cancelled out, of course. Second, I add some force that pulls on the actor in the direction of the rope in order to help the rope pull the actor back.

Had the other end of the rope, or its anchor (in your case the crane) been static you could just set the position directly to whatever the length of the wire is, but with two dynamic anchors (actors) the result will be that one actor will be able to put infinite force on the other actor by pulling the rope, and this might not be desired.

This "self-made" rope limit won't work unless the rope is all straight, if it collides with something and gets bent this sollution won't work, naturally. Well, not unless you re-calculate the distance for the limit, that is.

This way I got a rope where I could control the stretch to what I need. Zero stretch works great. I got the result I needed but I don't know how much of help this is to you for your crane simulation. I guess you can dynamically change the length of your wire, and this might complicate things even further. Good luck though!

Re: Rope with heavy rigid body attached

Posted: Tue Aug 16, 2011 12:53 pm
by vic____

I am having the same problem. Soft body rope stretches, even with stiffness = 1. Though I am going to try now, a chain of rigid bodies and constraints might lead to instabilities (or so I read in this forum elsewhere,

could you please share the code you use to tweak the dynamics of the rope?



Re: Rope with heavy rigid body attached

Posted: Wed Aug 17, 2011 1:55 pm
by Thor Erling
Thanks for the response

I have tried your suggestion by force and velocity, I got stabillity problems (maybee I did something wrong). In addition I also have tried to reset the Node.m_x vector with partly success.
I will continue to search for solution of this problem and post on the forum if I solve it and hope others also will do so :D .

Below is the code I wrote to solve the problem. It helps on the stiffness, but not complete. The code is from a subclass of btSoftBody where I override the
"void btSoftBody::predictMotion(btScalar dt)" method (had to make the btSoftBody::predictMotion(btScalar dt) virtual)

Code: Select all

/*member variables */
  m_adjustNodeLength = adjustNodeLength;
  m_factor = 0.95f;

btVector3 adjustVector(btScalar dl, btVector3& prev,btVector3& v, btScalar factor)
  btVector3 c = v;
  c -= prev;
  btScalar l = c.length();
  if(dl/l > factor)
    return v;
  c *= dl/(l*factor);
  c += prev;
  return c;

bool	JniSoftBody::adjustNodeLengths(btScalar dt)
    return false;
  if(m_links.size() != m_nodes.size() -1)
    return false;

	int i,ni;

	/* Update				*/ 

	/* Prepare */
	m_sst.sdt		=	dt*m_cfg.timescale;
	m_sst.isdt		=	1/m_sst.sdt;
	m_sst.velmrg	=	m_sst.sdt*3;
	m_sst.radmrg	=	getCollisionShape()->getMargin();
	m_sst.updmrg	=	m_sst.radmrg*(btScalar)0.25;
	/* Forces	*/ 
/* Making rope stiff using force (Not successfull)
		Node&	c=m_nodes[i];
		Node&	p=m_nodes[i - 1];
		Link&	d=m_links[i - 1];
    btVector3 v = c.m_x - p.m_x;
    btScalar l = v.length();
    btScalar dl = l - d.m_rl;
    v = v.normalize();
    if(dl > 0)
      v *= -(dl*dl)*1000;
      v *= dl*dl;
    addForce(v, i);

	/* Integrate			*/ 
		Node&	n=m_nodes[i];
		n.m_q	=	n.m_x;
		n.m_v	+=	n.m_f*n.m_im*m_sst.sdt;
    n.m_x	+=	n.m_v*m_sst.sdt;
/*Start: Making rope stiff by moving Node.m_x (Partly successfull)*/
		if(i > 0)
      Node&	p=m_nodes[i - 1];
		  Link&	d=m_links[i - 1];
      n.m_x = adjustVector(d.m_rl, p.m_x, n.m_x, m_factor);
/*End Making rope stiff by moving Node.m_x*/
    n.m_f	=	btVector3(0,0,0);
/*Moving anchors to rope node (Partly successfull. The swing of rigid body is heavaly damped)
  for(int i=0; i < m_anchors.size();++i)
    Anchor a = m_anchors[i];
    btScalar dl =  a.m_local.length();
    btTransform t = a.m_body->getWorldTransform();
    btVector3 v = t.getOrigin();
    v = adjustVector(dl, a.m_node->m_x, v, m_factor);

	/* Clusters				*/ 
	/* Bounds				*/ 
	/* Nodes				*/ 
	ATTRIBUTE_ALIGNED16(btDbvtVolume)	vol;
		Node&	n=m_nodes[i];
		vol = btDbvtVolume::FromCR(n.m_x,m_sst.radmrg);
		m_ndbvt.update(	n.m_leaf,
	/* Faces				*/ 
		for(int i=0;i<m_faces.size();++i)
			Face&			f=m_faces[i];
			const btVector3	v=(	f.m_n[0]->m_v+
			vol = VolumeOf(f,m_sst.radmrg);
			m_fdbvt.update(	f.m_leaf,
	/* Pose					*/ 
	/* Match				*/ 
		const btMatrix3x3	posetrs=m_pose.m_rot;
		for(int i=0,ni=m_nodes.size();i<ni;++i)
			Node&	n=m_nodes[i];
				const btVector3	x=posetrs*m_pose.m_pos[i]+m_pose.m_com;

/* Clear contacts		*/ 
	/* Optimize dbvt's		*/ 
  return true;
void	JniSoftBody::predictMotion(btScalar dt)

Re: Rope with heavy rigid body attached

Posted: Thu Aug 18, 2011 1:43 am
by mi076
We are using bullet for making a realistic offshore crane simulator. An important part of this simulation is hanging heavy load in a wire when a ship is moving.
AFAIK, it could be too much for real time...
Look at ... 95&p=23208
it is about Dynamica, but may be interesting...

Re: Rope with heavy rigid body attached

Posted: Tue Jul 17, 2012 12:43 am
by brtietz

I was noticing similar problems in my work. I didn't opt for Gaston's solution, since both of my bodies need to be active. I was not able to solve the problem completely (ie, the rope can still stretch past its rest length), but I did find that there was a vast improvement in stiffness using stiffness value 1 by running the softbodied solver for multiple iterations. With a string of mass 10 and a box of mass 50, the extra decreased from 20% to 3%. You can set these for each individual softbody like in the demo:

psb->m_cfg.piterations = 10;
psb->m_cfg.citerations = 10;
psb->m_cfg.diterations = 10;
psb->m_cfg.viterations = 10;

Good luck!

Re: Rope with heavy rigid body attached

Posted: Thu Jul 19, 2012 10:19 am
by qupie
One way to fix stiffness is having unequal set of node mass for the rope. The closer to the crane use more mass to nodes than the ones closer to the load.