## pyode-user

 [Pyode-user] holding an object at a certain level with a chain From: nick knouf - 2007-06-19 17:04:19 ```Hello PyODE list, I posted something similar to this on the ODE list recently but didn't receive any responses, so I thought I'd try here (also since I'm using PyODE). I have a rectangular box (mostly in the xz plane) with 4 chains in the +y direction, attached with ball joints on the corners of the box. I want to use the chains to hold the box above the floor. I'm able to do this without a problem; the box hovers above the ground with the chains taut and the top element of the chain within +-0.01 or so of the desired position. But, let's say I want to pull up one corner of the box by applying work to one chain. I can do this, the box corner moves up, I get a new desired hold position. But my holding algorithm does not hold the chain at the desired position; the x and z components hover within +- 0.01 of the desired position, but once I stop applying the additional force, the corner slips downward (-y), with the y position often off by -4.0 or more. Pseudo-code for the holding algorithm (in both cases described above) is as follows: currentVelocity = finalChainElement.getLinearVel() currentPosition = finalChainElement.getPosition() desiredPosition = holdPosition desiredVelocity = desiredPosition - currentPosition desiredAccel = desiredVeclocity - currentVelocity finalChainElement.addForce(holdingMass * desiredAcel + holdingForce) Is there something in my algorithm that seems wrong? I've tried various combinations of lookahead and PID controllers to no avail. I'm using the latest PyODE and ODE 0.8. Thanks for any help! This should be simple and it's been stumping me for a while... nick ```
 Re: [Pyode-user] holding an object at a certain level with a chain From: Ethan Glasser-Camp - 2007-06-19 18:25:19 ```Sorry Nick for the duplicate mail.. nick knouf wrote: > I have a rectangular box (mostly in the xz plane) with 4 chains in > the +y direction, attached with ball joints on the corners of the > box. I want to use the chains to hold the box above the floor. How did you build chains using ODE? (This is personal curiosity; the most effective chains I've been able to build have been hinge joint + slider, but that's only in 2D.) > Pseudo-code for the holding algorithm (in both cases described above) > is as follows: > > currentVelocity = finalChainElement.getLinearVel() > currentPosition = finalChainElement.getPosition() > desiredPosition = holdPosition > > desiredVelocity = desiredPosition - currentPosition > desiredAccel = desiredVeclocity - currentVelocity > finalChainElement.addForce(holdingMass * desiredAcel + holdingForce) I'm not sure but this looks like you should be using some kind of motor instead of computing forces like this. Ethan ```
 Re: [Pyode-user] holding an object at a certain level with a chain From: nick knouf - 2007-06-19 18:45:58 ```(I thought I should send my response to the entire list as well...sorry for the duplicate e-mail Ethan) On Jun 19, 2007, at 2:24 PM, Ethan Glasser-Camp wrote: > How did you build chains using ODE? (This is personal curiosity; the > most effective chains I've been able to build have been hinge joint + > slider, but that's only in 2D.) Thanks Ethan. I basically based my chains on the examples that come with the ODE distribution (specifically "ode/test/test_chain1.c"). I've included my (not-very-well commented) code below. I model each chain as a GeomCapsule and attach them to each other using ball joints. I'm able to get 20 links in the chain without a problem, and with expected bending behavior (screenshot: http://zeitkunst.org/ media/images/chains.png). Applying all types of forces to the chain gives reasonably expected movement and bending of the chains. > I'm not sure but this looks like you should be using some kind of > motor instead of computing forces like this. Does anyone have good references for using motors? I've looked a bit at the examples on the PyODE website, but would appreciate other suggestions. Thanks, nick xPosition, yPosition, zPosition = initialPosition for linkNumber in range(self.numLinks): link = ode.Body(self.world) M = ode.Mass() M.setBox(density, size[0], size[1], size[2]) M.adjust(0.5) link.setMass(M) # offset the start position by half of the y dimension k = (linkNumber * size[1]) + (initialPosition[1] + size [1]/2.0) link.setPosition((initialPosition[0], k, initialPosition [2])) link.currentPosition = (initialPosition[0], k, initialPosition[2]) yPosition += size[1] - 0.1 self.bodies.append(link) geom = ode.GeomCapsule(self.space, radius = self.size[1]/ 2.0, length=self.size[0]) geom.setBody(link) self.geom.append(geom) self.bodyHoldPosition = array((initialPosition[0], k, initialPosition[2])) # create joint with creature joint = ode.BallJoint(self.world) joint.attach(self.bodies[0], self.creatureBody) joint.setAnchor((initialPosition[0], initialPosition[1] - size[1]/2.0, initialPosition[2])) self.joints.append(joint) for linkNumber in range(self.numLinks - 1): joint = ode.BallJoint(self.world) joint.attach(self.bodies[linkNumber], self.bodies [linkNumber + 1]) k = (linkNumber + 1) * size[1] + initialPosition[1] - size[1]/2.0 joint.setAnchor((initialPosition[0], k, initialPosition [2])) self.joints.append(joint) ```