Moderators: Sascha Willems, walaber
MeltingPlastic wrote:How would one get the forces needed to create a specified linear and rotational acceleration?
MeltingPlastic wrote:Yeah I think that's what I mean. I am getting more into robotics. I would actually think that exposing the skeleton from any ndJoint or body would be fine too.
class ndModel: public ndClassAlloc
{
public:
ndModel();
virtual ~ndModel ();
....
virtual ndSkeletonContainer* GetSkeleton() const;
}
inline ndSkeletonContainer* ndMultiBodyVehicle::GetSkeleton() const
{
return m_chassis ? m_chassis->GetSkeleton() : nullptr;
}
JoeJ wrote:What i want is to give a target pose to Newton, which then tries to reach it.
Though, i already can do just that using the old joint motors. It's how my old ragdoll stuff worked - I did calculate motor joint accelerations from the pose.
The system is meant to take effector targets, and do all the rest on its own, including balance and the IK problem to find a pose? (Not sure if this is still the plan.)
Julio Jerez wrote:in an ideal world that works. but in practice, joint hit limits as they move.
and one a joint hit a limit it is too late for making a correction.
[/quote]You assembly the articulation with end effector at the tip.
Them in the pre step, you move the effector to a desire position, and you call the function to calculate the torque.
void ndDynamicsUpdate::CalculateForces()
{
D_TRACKTIME();
if (m_world->GetScene()->GetActiveContactArray().GetCount())
{
m_firstPassCoef = ndFloat32(0.0f);
if (m_world->m_skeletonList.GetCount())
{
InitSkeletons();
}
for (ndInt32 step = 0; step < 4; step++)
{
CalculateJointsAcceleration();
CalculateJointsForce();
if (m_world->m_skeletonList.GetCount())
{
UpdateSkeletons();
}
IntegrateBodiesVelocity();
}
UpdateForceFeedback();
}
}
void ndDynamicsUpdate::UpdateForceFeedback()
{
D_TRACKTIME();
ndScene* const scene = m_world->GetScene();
const ndArray<ndConstraint*>& jointArray = scene->GetActiveContactArray();
auto UpdateForceFeedback = ndMakeObject::ndFunction([this, &jointArray](ndInt32 threadIndex, ndInt32 threadCount)
{
D_TRACKTIME();
ndArray<ndRightHandSide>& rightHandSide = m_rightHandSide;
const ndArray<ndLeftHandSide>& leftHandSide = m_leftHandSide;
const ndVector zero(ndVector::m_zero);
const ndFloat32 timestepRK = GetTimestepRK();
const ndStartEnd startEnd(jointArray.GetCount(), threadIndex, threadCount);
for (ndInt32 i = startEnd.m_start; i < startEnd.m_end; ++i)
{
ndConstraint* const joint = jointArray[i];
const ndInt32 rows = joint->m_rowCount;
const ndInt32 first = joint->m_rowStart;
for (ndInt32 j = 0; j < rows; ++j)
{
const ndRightHandSide* const rhs = &rightHandSide[j + first];
dAssert(dCheckFloat(rhs->m_force));
rhs->m_jointFeebackForce->Push(rhs->m_force);
rhs->m_jointFeebackForce->m_force = rhs->m_force;
rhs->m_jointFeebackForce->m_impact = rhs->m_maxImpact * timestepRK;
}
if (joint->GetAsBilateral())
{
ndVector force0(zero);
ndVector force1(zero);
ndVector torque0(zero);
ndVector torque1(zero);
for (ndInt32 j = 0; j < rows; ++j)
{
const ndRightHandSide* const rhs = &rightHandSide[j + first];
const ndLeftHandSide* const lhs = &leftHandSide[j + first];
const ndVector f(rhs->m_force);
force0 += lhs->m_Jt.m_jacobianM0.m_linear * f;
torque0 += lhs->m_Jt.m_jacobianM0.m_angular * f;
force1 += lhs->m_Jt.m_jacobianM1.m_linear * f;
torque1 += lhs->m_Jt.m_jacobianM1.m_angular * f;
}
ndJointBilateralConstraint* const bilateral = (ndJointBilateralConstraint*)joint;
bilateral->m_forceBody0 = force0;
bilateral->m_torqueBody0 = torque0;
bilateral->m_forceBody1 = force1;
bilateral->m_torqueBody1 = torque1;
}
}
});
scene->ParallelExecute(UpdateForceFeedback);
}
Users browsing this forum: No registered users and 46 guests