7 #include "imstkProgrammableClient.h" 8 #include "imstkLogger.h" 9 #include "imstkCapsule.h" 17 for (
auto cmd : m_commands)
28 for (
auto cmd : m_commands)
30 total += cmd->duration;
44 LOG(WARNING) <<
"warning: No update period set";
50 m_currentTime += m_dt;
51 for (
auto cmd : m_commands)
53 if (cmd->state == CommandState::WAITING && m_currentTime > cmd->startTime)
57 else if (cmd->state == CommandState::ACTIVE && m_currentTime >= cmd->startTime + cmd->duration)
62 if (cmd->state == CommandState::ACTIVE)
65 cmd->updateDevice(*
this);
67 else if (cmd->state == CommandState::COMPLETE)
75 if (complete == m_commands.size())
84 if (startPos == stopPos)
86 LOG(WARNING) <<
"warning: No travel set";
91 LOG(WARNING) <<
"warning: No duration set";
96 move->startPosition = startPos;
97 move->stopPosition = stopPos;
98 move->startTime = startTime;
99 move->duration = duration;
100 m_commands.push_back(move);
107 Command::activate(pc);
109 pc.
m_velocity = ((stopPosition - startPosition) / duration);
121 Command::complete(pc);
130 LOG(WARNING) <<
"warning: No duration set";
135 move->startPosition = startPos;
136 move->centerPosition = centerPos;
137 move->radius = (startPos - centerPos).norm();
138 move->angle = acos((startPos[0] / move->radius) - centerPos[0]);
139 move->angleStep = 2 * PI / (duration / m_dt);
140 move->startTime = startTime;
141 move->duration = duration;
142 m_commands.push_back(move);
149 Command::activate(pc);
150 pc.
m_position[0] = centerPosition[0] + (cos(angle) * radius);
152 pc.
m_position[2] = centerPosition[2] + (sin(angle) * radius);
160 pc.
m_position[0] = centerPosition[0] + (cos(angle) * radius);
162 pc.
m_position[2] = centerPosition[2] + (sin(angle) * radius);
169 Command::complete(pc);
170 pc.
m_position[0] = centerPosition[0] + (cos(0) * radius);
172 pc.
m_position[2] = centerPosition[2] + (sin(0) * radius);
181 grasp->objectGrasping = objectGrasping;
182 grasp->startTime = startTime;
183 grasp->duration = duration;
184 m_commands.push_back(grasp);
191 Command::activate(pc);
192 objectGrasping->beginVertexGrasp(std::dynamic_pointer_cast<Capsule>(tool->getPhysicsGeometry()));
198 Command::complete(pc);
199 objectGrasping->endGrasp();
204 std::shared_ptr<PbdObject>
object,
205 std::vector<int> vertexIds,
207 std::vector<bool> pin,
211 if (translation == Vec3d::Zero())
213 LOG(WARNING) <<
"warning: No travel set";
217 LOG(WARNING) <<
"warning: No duration set";
222 move->object = object;
223 move->translation = translation;
224 move->startTime = startTime;
225 move->duration = duration;
226 move->vertexIds = vertexIds;
229 if (move->vertexIds.empty())
231 LOG(WARNING) <<
"warning: Invalid initial position for vertex";
235 m_commands.push_back(move);
242 Command::activate(pc);
244 for (
int i = 0; i < vertexIds.size(); i++)
246 currPos.push_back((*object->getPbdBody()->vertices)[vertexIds[i]]);
253 for (
int i = 0; i < vertexIds.size(); i++)
255 for (
int dim = 0; dim < 3; dim++)
259 currPos[i][dim] += (pc.
m_velocity[dim] * pc.m_dt);
263 currPos[i][dim] = (*
object->getPbdBody()->vertices)[vertexIds[i]][dim];
267 (*
object->getPbdBody()->vertices)[vertexIds[i]] = currPos[i];
268 (*
object->getPbdBody()->velocities)[vertexIds[i]] = Vec3d::Zero();
275 Command::complete(pc);
280 std::shared_ptr<PbdObject>
object,
281 std::vector<int> vertexIds,
285 std::vector<bool> pin,
286 double startTime,
double duration)
290 LOG(WARNING) <<
"warning: No duration set in addDeformation for ProgrammableClient";
295 deform->object = object;
296 deform->strain = strain;
297 deform->startTime = startTime;
298 deform->duration = duration;
299 deform->vertexIds = vertexIds;
301 deform->type = defType;
302 deform->poissons = poisson;
304 if (deform->vertexIds.empty())
306 LOG(WARNING) <<
"warning: Invalid initial position for vertex";
310 m_commands.push_back(deform);
317 Command::activate(pc);
318 strainRate = strain / duration;
324 auto mesh = std::dynamic_pointer_cast<
PointSet>(
object->getPhysicsGeometry());
328 std::shared_ptr<VecDataArray<double, 3>> verticesPtr = mesh->getVertexPositions();
331 double volFac = poissons * 2.0;
333 if (type == DeformationType::Compression)
335 double isoCompression = sqrt(1.0 / (1.0 - strainRate * pc.m_dt)) - 1.0;
337 { isoCompression* volFac, 0.0, 0.0 },
338 { 0.0, -strainRate * pc.m_dt, 0.0 },
339 { 0.0, 0.0, isoCompression* volFac } };
341 defGrad += compression;
343 else if (type == DeformationType::Tension)
345 double isoTension = sqrt(1.0 / (1.0 + strainRate * pc.m_dt)) - 1.0;
348 { isoTension* volFac, 0.0, 0.0 },
349 { 0.0, strainRate* pc.m_dt, 0.0 },
350 { 0.0, 0.0, isoTension* volFac } };
354 else if (type == DeformationType::SimpleShear)
356 double gamma = strainRate * pc.m_dt;
362 defGrad += simpleShear;
364 else if (type == DeformationType::PureShear)
366 double gamma = strainRate * pc.m_dt;
372 defGrad += pureShear;
375 for (
int i = 0; i < vertexIds.size(); i++)
377 vertices[vertexIds[i]] = defGrad * initVertices[vertexIds[i]];
378 (*
object->getPbdBody()->vertices)[vertexIds[i]] = vertices[vertexIds[i]];
385 Command::complete(pc);
389 ProgrammableClient::findVertex(std::shared_ptr<PointSet> mesh, std::vector<Vec3d> initPos)
391 std::vector<int> ids;
392 for (Vec3d pos : initPos)
394 for (
int i = 0; i < mesh->getNumVertices(); i++)
396 if (pos.isApprox(mesh->getInitialVertexPosition(i)))
411 LOG(WARNING) <<
"warning: No duration set";
416 wait->startTime = startTime;
417 wait->duration = duration;
418 m_commands.push_back(wait);
427 LOG(WARNING) <<
"warning: No duration set";
431 if (vertexIds.size() <= 0)
433 LOG(WARNING) <<
"warning: Vertices to hold in addHoldCommand";
438 hold->object = object;
439 hold->vertexIds = vertexIds;
440 hold->startTime = startTime;
441 hold->duration = duration;
443 m_commands.push_back(hold);
450 Command::activate(pc);
453 if (object->getPhysicsGeometry()->isMesh())
455 auto mesh = std::dynamic_pointer_cast<
PointSet>(
object->getPhysicsGeometry());
459 for (
int vert = 0; vert < vertexIds.size(); vert++)
463 auto body =
object->getPbdBody();
464 (*body->invMasses)[vertexIds[vert]] = 0.0;
466 Vec3d pos = verticesPtr->at(vertexIds[vert]);
467 holdPosition.push_back(pos);
472 auto analyticalGeo = std::dynamic_pointer_cast<
AnalyticalGeometry>(
object->getPhysicsGeometry());
473 auto body =
object->getPbdBody();
474 (*body->invMasses)[vertexIds[0]] = 0.0;
477 holdPosition.push_back(pos);
484 if (object->getPhysicsGeometry()->isMesh())
486 auto mesh = std::dynamic_pointer_cast<
PointSet>(
object->getPhysicsGeometry());
491 for (
int i = 0; i < vertexIds.size(); i++)
493 vertices[vertexIds[i]] = holdPosition[i];
494 (*
object->getPbdBody()->velocities)[vertexIds[i]] = Vec3d::Zero();
499 auto analyticalGeo = std::dynamic_pointer_cast<
AnalyticalGeometry>(
object->getPhysicsGeometry());
502 (*
object->getPbdBody()->velocities)[vertexIds[0]] = Vec3d::Zero();
509 Command::complete(pc);
Base class for any analytical geometrical representation.
~ProgrammableClient() override
Destructor.
Command for holding a subset of vertices at a specific position.
Base class for all geometries represented by discrete points and elements The pointsets follow a pipe...
bool addGrasping(std::shared_ptr< PbdObject > tool, std::shared_ptr< PbdObjectGrasping > objectGrasping, double startTime, double duration)
Add a grasp command to run.
Vec3d m_angularVelocity
Angular velocity of the end effector.
Command for linear movement of a subset of vertices from an object.
bool addHoldCommand(std::shared_ptr< PbdObject > object, double startTime, double duration, std::vector< int > vertexIds)
Add a hold command to run.
double getTotalDuration()
Returns to total duration of all commands.
Vec3d getPosition(DataType type=DataType::PostTransform)
Get the local or global position (post transformed)
Vec3d getVelocity()
Get the device velocity.
bool addWaitCommand(double startTime, double duration)
Add a wait command to run.
bool addCircularMovement(Vec3d startPos, Vec3d centerPos, double startTime, double duration)
Add a circular movement command to run.
bool addLinearMovement(Vec3d startPos, Vec3d stopPos, double startTime, double duration)
Add a linear movement command to run.
DeformationType
Enum for type of deformation.
bool addDeformation(std::shared_ptr< PbdObject > object, std::vector< int > initPos, double strain, DeformationType defType, double poisson, std::vector< bool > pin, double startTime, double duration)
Add a defomation command to run.
Command for linear movement of an analytical geometry.
void setPosition(const Vec3d p)
Set the local position.
Vec3d m_velocity
Linear velocity of end effector.
Vec3d m_position
Position of end effector.
std::shared_ptr< VecDataArray< double, 3 > > getVertexPositions(DataType type=DataType::PostTransform) const
Returns the vector of current positions of the mesh vertices.
Command for waiting. Used to let system continue running with no active commands. ...
bool addLinearVertexMovement(std::shared_ptr< PbdObject > object, std::vector< int > vertexIds, Vec3d translation, std::vector< bool > pin, double startTime, double duration)
Add a linear vertex movement command to run.
void update() override
Update all commands.
Command for grasping an object.
std::shared_ptr< VecDataArray< double, 3 > > getInitialVertexPositions() const
Returns the vector of initial positions of the mesh vertices.
Command for applying deformationt to a subset of vertices from an object.
Command for circular movement of an analytical geometry.
Allows setting the pose of the device from external caller without a real device connected.