26 #include "TensegrityModel.h"
49 topLvlStructurePath = structurePath;
57 topLvlStructurePath = structurePath;
69 void TensegrityModel::trace(
const tgStructure& structure,
72 std::cout << std::endl <<
"Structure Trace inside TensegrityModel:" << std::endl
73 << structure << std::endl
74 << std::endl <<
"StructureInfo Trace inside TensegrityModel:" << std::endl
75 << structureInfo << std::endl
76 << std::endl <<
"tgModel Trace inside Tensegrity Model: " << std::endl
77 << model << std::endl;
92 addRodBuilder(
"tgRodInfo",
"rod", emptyYam, spec);
93 addBasicActuatorBuilder(
"tgBasicActuatorInfo",
"string", emptyYam, spec);
94 addBoxBuilder(
"tgBoxInfo",
"box", emptyYam, spec);
95 addSphereBuilder(
"tgSphereInfo",
"sphere", emptyYam, spec);
98 buildStructure(structure, topLvlStructurePath, spec);
104 allActuators = tgCast::filter<tgModel, tgSpringCableActuator> (
getDescendants());
108 trace(structure, structureInfo, *
this);
118 void TensegrityModel::addChildren(
tgStructure& structure,
const std::string& structurePath,
tgBuildSpec& spec,
const Yam& children) {
119 if (!children)
return;
120 std::string structureAttributeKeys[] = {
"path",
"rotation",
"translation",
"scale",
"offset"};
121 std::vector<std::string> structureAttributeKeysVector(structureAttributeKeys, structureAttributeKeys +
sizeof(structureAttributeKeys) /
sizeof(std::string));
124 for (YAML::const_iterator child = children.begin(); child != children.end(); ++child) {
125 Yam childAttributes = child->second;
126 yamlContainsOnly(childAttributes, structurePath, structureAttributeKeysVector);
129 std::string childCombos = child->first.as<std::string>() +
"/";
130 while (childCombos.find(
"/") != std::string::npos) {
131 std::string childName = childCombos.substr(0, childCombos.find(
"/"));
132 addChild(structure, structurePath, childName, childAttributes[
"path"], spec);
133 childCombos = childCombos.substr(childCombos.find(
"/") + 1);
138 for (YAML::const_iterator child = children.begin(); child != children.end(); ++child) {
139 Yam childAttributes = child->second;
142 std::string childCombos = child->first.as<std::string>() +
"/";
143 while (childCombos.find(
"/") != std::string::npos) {
144 std::string childName = childCombos.substr(0, childCombos.find(
"/"));
146 addChildRotation(childStructure, childAttributes[
"rotation"]);
147 childCombos = childCombos.substr(childCombos.find(
"/") + 1);
152 for (YAML::const_iterator child = children.begin(); child != children.end(); ++child) {
153 Yam childAttributes = child->second;
156 std::string childCombos = child->first.as<std::string>() +
"/";
157 int childComboIndex = 0;
158 while (childCombos.find(
"/") != std::string::npos) {
159 std::string childName = childCombos.substr(0, childCombos.find(
"/"));
161 addChildScale(childStructure, childAttributes[
"scale"]);
162 addChildOffset(childStructure, childComboIndex, childAttributes[
"offset"]);
163 addChildTranslation(childStructure, childAttributes[
"translation"]);
164 childCombos = childCombos.substr(childCombos.find(
"/") + 1);
170 void TensegrityModel::addChild(
tgStructure& structure,
const std::string &parentPath,
171 const std::string& childName,
const Yam& childStructurePath,
tgBuildSpec& spec) {
173 if (!childStructurePath)
return;
174 std::string childPath = childStructurePath.as<std::string>();
176 if (childPath[0] !=
'/') {
177 childPath = parentPath.substr(0, parentPath.rfind(
"/") + 1) + childPath;
180 buildStructure(childStructure, childPath, spec);
184 void TensegrityModel::addChildRotation(
tgStructure& childStructure,
const Yam& rotation) {
185 if (!rotation)
return;
186 Yam reference = rotation[
"reference"];
187 Yam axis = rotation[
"axis"];
188 Yam angle = rotation[
"angle"];
190 double axisX = axis[0].as<
double>();
191 double axisY = axis[1].as<
double>();
192 double axisZ = axis[2].as<
double>();
193 btVector3 axisVector = btVector3(axisX, axisY, axisZ);
194 double angleDegrees = angle.as<
double>();
196 btVector3 referenceVector;
199 double referenceX = reference[0].as<
double>();
200 double referenceY = reference[1].as<
double>();
201 double referenceZ = reference[2].as<
double>();
202 referenceVector = btVector3(referenceX, referenceY, referenceZ);
208 childStructure.
addRotation(referenceVector, axisVector, angleRadians);
212 void TensegrityModel::addChildScale(
tgStructure& childStructure,
const Yam& scale) {
214 double scaleFactor = scale.as<
double>();
215 childStructure.scale(scaleFactor);
218 void TensegrityModel::addChildOffset(
tgStructure& childStructure,
int offsetIndex,
const Yam& offset) {
220 double offsetX = offset[0].as<
double>();
221 double offsetY = offset[1].as<
double>();
222 double offsetZ = offset[2].as<
double>();
223 btVector3 offsetVector = btVector3(offsetX, offsetY, offsetZ);
224 childStructure.move(offsetVector * offsetIndex);
227 void TensegrityModel::addChildTranslation(
tgStructure& childStructure,
const Yam& translation) {
228 if (!translation)
return;
229 double translationX = translation[0].as<
double>();
230 double translationY = translation[1].as<
double>();
231 double translationZ = translation[2].as<
double>();
232 btVector3 translationVector = btVector3(translationX, translationY, translationZ);
233 childStructure.move(translationVector);
236 void TensegrityModel::buildStructure(
tgStructure& structure,
const std::string& structurePath,
tgBuildSpec& spec) {
245 root = YAML::LoadFile(structurePath);
247 catch( YAML::BadFile badfileexception )
250 std::cout << std::endl <<
"The YAML parser threw a BadFile exception when" <<
251 " trying to load one of your YAML files. " << std::endl <<
252 "The path of the structure that the parser attempted to load is: '" <<
253 structurePath <<
"'. " << std::endl <<
254 "Check to be sure that the file exists, and " <<
255 "that you didn't spell the path name incorrectly." <<
256 std::endl << std::endl;
258 throw badfileexception;
261 std::string rootKeys[] = {
"nodes",
"pair_groups",
"builders",
"substructures",
"bond_groups"};
262 std::vector<std::string> rootKeysVector(rootKeys, rootKeys +
sizeof(rootKeys) /
sizeof(std::string));
263 yamlContainsOnly(root, structurePath, rootKeysVector);
264 yamlNoDuplicates(root, structurePath);
266 addChildren(structure, structurePath, spec, root[
"substructures"]);
267 addBuilders(spec, root[
"builders"]);
268 addNodes(structure, root[
"nodes"]);
269 addPairGroups(structure, root[
"pair_groups"]);
270 addBondGroups(structure, root[
"bond_groups"], spec);
273 void TensegrityModel::addNodes(
tgStructure& structure,
const Yam& nodes) {
275 for (YAML::const_iterator node = nodes.begin(); node != nodes.end(); ++node) {
276 std::string name = node->first.as<std::string>();
277 Yam xyz = node->second;
278 double x = xyz[0].as<
double>();
279 double y = xyz[1].as<
double>();
280 double z = xyz[2].as<
double>();
281 structure.
addNode(x, y, z, name);
285 void TensegrityModel::addPairGroups(
tgStructure& structure,
const Yam& pair_groups) {
286 if (!pair_groups)
return;
287 for (YAML::const_iterator pair_group = pair_groups.begin(); pair_group != pair_groups.end(); ++pair_group) {
288 std::string tags = pair_group->first.as<std::string>();
289 Yam pairs = pair_group->second;
290 addNodeNodePairs(structure, tags, pairs);
295 if (!bond_groups)
return;
298 for (YAML::const_iterator firstLvl = bond_groups.begin(); firstLvl != bond_groups.end(); ++firstLvl) {
301 bool bondsSet =
false;
302 bool tagsSet =
false;
304 std::string firstLvlKey = firstLvl->first.as<std::string>();
305 Yam firstLvlContent = firstLvl->second;
307 if (firstLvlKey.find(
"/") == std::string::npos) {
317 for (YAML::const_iterator secondLvl = firstLvlContent.begin(); secondLvl != firstLvlContent.end(); ++secondLvl) {
318 std::string secondLvlKey = secondLvl->first.as<std::string>();
319 Yam secondLvlContent = secondLvl->second;
320 if (secondLvlKey.find(
"/") == std::string::npos) {
322 if (tagsSet)
throw std::invalid_argument(
"Invalid nesting of tags: "+ secondLvlKey);
326 if (bondsSet)
throw std::invalid_argument(
"Invalid nesting of bonds: " + secondLvlKey);
327 bonds = secondLvlKey;
329 addBonds(structure, bonds, tags, secondLvlContent, spec);
334 void TensegrityModel::addBonds(
tgStructure& structure,
const std::string& bonds,
const std::string& tags,
const Yam& pairs,
tgBuildSpec& spec) {
337 std::string bondType = bonds.substr(bonds.rfind(
"/") + 1);
338 std::string structureCombos = bonds.substr(0, bonds.rfind(
"/"));
339 if (structureCombos.find(
"/") == std::string::npos)
340 throw std::invalid_argument(
"Error: all bond groups must specify a bond between 2 or more structures and a bond type");
341 while (structureCombos.find(
"/") != std::string::npos) {
342 std::string childStructure1Name = structureCombos.substr(0, structureCombos.find(
"/"));
343 structureCombos = structureCombos.substr(structureCombos.find(
"/") + 1);
344 std::string childStructure2Name = structureCombos.substr(0, structureCombos.find(
"/"));
345 if (bondType ==
"node_node") {
348 std::cout <<
"Adding node_node bonds " << tags <<
349 " between structures " << childStructure1Name <<
350 " and " << childStructure2Name << std::endl;
353 addNodeNodePairs(structure, tags, pairs, &childStructure1Name,
354 &childStructure2Name);
356 else if (bondType ==
"node_edge") {
357 addNodeEdgePairs(structure, tags, pairs, &childStructure1Name, &childStructure2Name, spec);
360 throw std::invalid_argument(
"Unsupported bond type: " + bondType);
365 void TensegrityModel::addNodeNodePairs(
tgStructure& structure,
366 const std::string& tags,
const Yam& pairs,
367 const std::string* childStructure1Name,
368 const std::string* childStructure2Name) {
377 if (childStructure1Name && childStructure2Name) {
378 std::cout <<
"Adding all the node_node pairs between structures "
379 << *childStructure1Name <<
" and " << *childStructure2Name
383 std::cout <<
"Adding all the node_node pairs within a base structure." <<
388 for (YAML::const_iterator pairPtr = pairs.begin(); pairPtr != pairs.end(); ++pairPtr) {
390 std::string node1Path = pair[0].as<std::string>();
391 std::string node2Path = pair[1].as<std::string>();
396 std::string pairNewTags = tags;
398 if (childStructure1Name && childStructure2Name) {
399 node1 = &getNode(structure.
findChild(*childStructure1Name), node1Path);
400 node2 = &getNode(structure.
findChild(*childStructure2Name), node2Path);
403 std::cout <<
"Adding node_node pair " << tags <<
" between structures "
404 << *childStructure1Name <<
" and " << *childStructure2Name
405 <<
" for nodes " << *node1 <<
" and " << *node2
406 <<
" with original tag " << tags << std::endl;
414 pairNewTags = tags +
" " + *childStructure1Name +
" " + *childStructure2Name
415 +
" " + *childStructure1Name +
"/" + *childStructure2Name;
420 node1 = &getNode(structure, node1Path);
421 node2 = &getNode(structure, node2Path);
425 structure.
addPair(*node1, *node2, pairNewTags);
429 void TensegrityModel::addNodeEdgePairs(
tgStructure& structure,
const std::string& tags,
const Yam& pairs,
430 const std::string* childStructure1Name,
const std::string* childStructure2Name,
tgBuildSpec& spec) {
432 if (pairs.size() < 3) {
433 throw std::invalid_argument(
"Error: node_edge bonds must specify at least 3 node_edge pairs");
440 std::vector<btVector3> structure1RefNodes;
441 std::vector<btVector3> structure2RefNodes;
444 std::vector<tgNode*> ligands;
446 std::vector< std::pair<tgNode*, tgNode*> > receptors;
449 parseNodeEdgePairs(childStructure1, childStructure2, structure1RefNodes, structure2RefNodes, ligands, receptors, pairs);
450 rotateAndTranslate(childStructure2, structure1RefNodes, structure2RefNodes);
452 std::vector<tgBuildSpec::RigidAgent*> rigidAgents = spec.getRigidAgents();
453 for (
unsigned int i = 0; i < ligands.size(); i++) {
458 removePair(childStructure1, receptors[i].first, receptors[i].second,
true, rigidAgents, spec);
459 removePair(childStructure2, receptors[i].first, receptors[i].second,
true, rigidAgents, spec);
460 for (
unsigned int j = 0; j < ligands.size(); j++) {
463 removePair(childStructure1, ligands[i], ligands[j],
false, rigidAgents, spec);
464 removePair(childStructure2, ligands[i], ligands[j],
false, rigidAgents, spec);
467 structure.
addPair(*(receptors[i].first), *ligands[i], tags);
468 structure.
addPair(*ligands[i], *(receptors[i].second), tags);
474 std::vector<btVector3>& structure1RefNodes, std::vector<btVector3>& structure2RefNodes,
475 std::vector<tgNode*>& ligands, std::vector< std::pair<tgNode*, tgNode*> >& receptors,
const Yam& pairs) {
477 for (YAML::const_iterator pairPtr = pairs.begin(); pairPtr != pairs.end(); ++pairPtr) {
480 std::string structure1Attachment = pair[0].as<std::string>();
481 std::string structure2Attachment = pair[1].as<std::string>();
484 if (structure1Attachment.find(
"/") == std::string::npos && structure2Attachment.find(
"/") == std::string::npos) {
485 throw std::invalid_argument(
"Invalid node_edge bond: " + structure1Attachment +
", " + structure2Attachment);
487 if (structure1Attachment.find(
"/") != std::string::npos && structure2Attachment.find(
"/") != std::string::npos) {
488 throw std::invalid_argument(
"Invalid node_edge bond: " + structure1Attachment +
", " + structure2Attachment);
490 parseAttachmentPoint(childStructure1, structure1Attachment, structure1RefNodes, ligands, receptors);
491 parseAttachmentPoint(childStructure2, structure2Attachment, structure2RefNodes, ligands, receptors);
495 void TensegrityModel::parseAttachmentPoint(
tgStructure& structure,
const std::string& attachment, std::vector<btVector3>& refNodes,
496 std::vector<tgNode*>& ligands, std::vector< std::pair<tgNode*, tgNode*> >& receptors) {
497 if (attachment.find(
"/") == std::string::npos) {
498 tgNode* attachmentNode = &(getNode(structure, attachment));
499 ligands.push_back(attachmentNode);
500 refNodes.push_back(*attachmentNode);
503 std::string attachmentNode1Path = attachment.substr(0, attachment.find(
"/"));
504 std::string attachmentNode2Path = attachment.substr(attachment.find(
"/") + 1);
506 tgNode* attachmentNode1 = &(getNode(structure, attachmentNode1Path));
507 tgNode* attachmentNode2 = &(getNode(structure, attachmentNode2Path));
509 receptors.push_back(std::make_pair(attachmentNode1, attachmentNode2));
510 refNodes.push_back((*attachmentNode1 + *attachmentNode2) / 2);
515 void TensegrityModel::rotateAndTranslate(
tgStructure& childStructure2,
516 std::vector<btVector3>& structure1RefNodes, std::vector<btVector3>& structure2RefNodes) {
521 btVector3 structure1PlaneNormal = ((structure1RefNodes[1] - structure1RefNodes[0]).
522 cross(structure1RefNodes[2] - structure1RefNodes[0])).normalize();
523 btVector3 structure2PlaneNormal = ((structure2RefNodes[1] - structure2RefNodes[0]).
524 cross(structure2RefNodes[2] - structure2RefNodes[0])).normalize();
527 btVector3 fallBackAxis = (structure2RefNodes[1] - structure2RefNodes[0]).normalize();
528 childStructure2.
addRotation(structure2RefNodesCentroid,
538 childStructure2.move(structure1RefNodesCentroid - structure2RefNodesCentroid);
541 structure2RefNodes[0] += structure1RefNodesCentroid - structure2RefNodesCentroid;
542 structure2RefNodesCentroid += structure1RefNodesCentroid - structure2RefNodesCentroid;
545 childStructure2.
addRotation(structure1RefNodesCentroid,
547 structure1RefNodes[0] - structure1RefNodesCentroid, structure1PlaneNormal));
551 void TensegrityModel::removePair(
tgStructure& structure,
const tgNode* from,
const tgNode* to,
bool isEdgePair,
552 const std::vector<tgBuildSpec::RigidAgent*>& rigidAgents,
tgBuildSpec& spec) {
556 pair = &structure.
findPair(*from, *to);
557 }
catch (std::invalid_argument e) {
560 for (
int i = 0; i < rigidAgents.size(); i++) {
562 if (tagSearch.
matches(*pair)) {
565 throw std::invalid_argument(
"Edges in node_edge bonds cannot be rods");
570 structure.removePair(*pair);
573 tgNode& TensegrityModel::getNode(
tgStructure& structure,
const std::string& nodePath) {
575 if (nodePath.find(
".") == std::string::npos) {
576 return structure.
findNode(nodePath);
579 std::string structurePath = nodePath.substr(0, nodePath.rfind(
"."));
580 std::string nodeName = nodePath.substr(nodePath.rfind(
".") + 1);
581 tgStructure& targetStructure = getStructure(structure, structurePath);
582 return targetStructure.
findNode(nodeName);
586 tgStructure& TensegrityModel::getStructure(
tgStructure& parentStructure,
const std::string& childStructurePath) {
588 if (childStructurePath.find(
".") == std::string::npos) {
589 return parentStructure.
findChild(childStructurePath);
592 std::string childStructureName = childStructurePath.substr(0, childStructurePath.rfind(
"."));
593 std::string remainingChildStructurePath = childStructurePath.substr(childStructurePath.rfind(
".") + 1);
595 return getStructure(childStructure, remainingChildStructurePath);
599 void TensegrityModel::addBuilders(
tgBuildSpec& spec,
const Yam& builders) {
600 for (YAML::const_iterator builder = builders.begin(); builder != builders.end(); ++builder) {
601 std::string tagMatch = builder->first.as<std::string>();
602 if (!builder->second[
"class"])
throw std::invalid_argument(
"Builder class not supplied for tag: " + tagMatch);
603 std::string builderClass = builder->second[
"class"].as<std::string>();
604 Yam parameters = builder->second[
"parameters"];
606 if (builderClass ==
"tgRodInfo") {
607 addRodBuilder(builderClass, tagMatch, parameters, spec);
609 else if (builderClass ==
"tgBasicActuatorInfo" || builderClass ==
"tgBasicContactCableInfo") {
610 addBasicActuatorBuilder(builderClass, tagMatch, parameters, spec);
612 else if (builderClass ==
"tgKinematicContactCableInfo" || builderClass ==
"tgKinematicActuatorInfo") {
613 addKinematicActuatorBuilder(builderClass, tagMatch, parameters, spec);
615 else if (builderClass ==
"tgBoxInfo") {
616 addBoxBuilder(builderClass, tagMatch, parameters, spec);
618 else if (builderClass ==
"tgSphereInfo") {
619 addSphereBuilder(builderClass, tagMatch, parameters, spec);
623 throw std::invalid_argument(
"Unsupported builder class: " + builderClass);
628 void TensegrityModel::addRodBuilder(
const std::string& builderClass,
const std::string& tagMatch,
const Yam& parameters,
tgBuildSpec& spec) {
630 std::map<std::string, double> rp;
632 rp[
"density"] = rodDensity;
633 rp[
"friction"] = rodFriction;
634 rp[
"roll_friction"] = rodRollFriction;
635 rp[
"restitution"] = rodRestitution;
638 for (YAML::const_iterator parameter = parameters.begin(); parameter != parameters.end(); ++parameter) {
639 std::string parameterName = parameter->first.as<std::string>();
640 if (rp.find(parameterName) == rp.end()) {
641 throw std::invalid_argument(
"Unsupported " + builderClass +
" parameter: " + parameterName);
644 rp[parameterName] = parameter->second.as<
double>();
649 rp[
"roll_friction"], rp[
"restitution"]);
650 if (builderClass ==
"tgRodInfo") {
652 spec.addBuilder(tagMatch,
new tgRodInfo(rodConfig));
657 void TensegrityModel::addBasicActuatorBuilder(
const std::string& builderClass,
const std::string& tagMatch,
const Yam& parameters,
tgBuildSpec& spec) {
665 std::map<std::string, double> bap_doubles;
666 std::map<std::string, bool> bap_booleans;
667 bap_doubles[
"stiffness"] = stringStiffness;
668 bap_doubles[
"damping"] = stringDamping;
669 bap_doubles[
"pretension"] = stringPretension;
670 bap_doubles[
"history"] = stringHistory;
671 bap_doubles[
"max_tension"] = stringMaxTension;
672 bap_doubles[
"target_velocity"] = stringTargetVelocity;
673 bap_doubles[
"min_actual_length"] = stringMinActualLength;
674 bap_doubles[
"min_rest_length"] = stringMinRestLength;
675 bap_doubles[
"rotation"] = stringRotation;
676 bap_booleans[
"moveCablePointAToEdge"] = stringMoveCablePointAToEdge;
677 bap_booleans[
"moveCablePointBToEdge"] = stringMoveCablePointBToEdge;
682 for (YAML::const_iterator parameter = parameters.begin(); parameter != parameters.end(); ++parameter) {
684 std::string parameterName = parameter->first.as<std::string>();
687 bool paramIsDouble =
true;
689 if( bap_doubles.find(parameterName) == bap_doubles.end()) {
691 paramIsDouble =
false;
693 if( bap_booleans.find(parameterName) == bap_booleans.end()) {
695 throw std::invalid_argument(
"Unsupported " + builderClass +
" parameter: " + parameterName);
699 if( paramIsDouble ) {
701 bap_doubles[parameterName] = parameter->second.as<
double>();
705 bap_booleans[parameterName] = parameter->second.as<
bool>();
719 bap_doubles[
"pretension"], bap_doubles[
"history"],
720 bap_doubles[
"max_tension"],
721 bap_doubles[
"target_velocity"],
722 bap_doubles[
"min_actual_length"],
723 bap_doubles[
"min_rest_length"],
724 bap_doubles[
"rotation"],
725 bap_booleans[
"moveCablePointAToEdge"],
726 bap_booleans[
"moveCablePointBToEdge"]);
727 if (builderClass ==
"tgBasicActuatorInfo") {
731 else if (builderClass ==
"tgBasicContactCableInfo") {
738 void TensegrityModel::addKinematicActuatorBuilder(
const std::string& builderClass,
const std::string& tagMatch,
const Yam& parameters,
tgBuildSpec& spec) {
740 std::map<std::string, double> kap;
741 kap[
"stiffness"] = stringStiffness;
742 kap[
"damping"] = stringDamping;
743 kap[
"pretension"] = stringPretension;
744 kap[
"radius"] = stringRadius;
745 kap[
"motor_friction"] = stringMotorFriction;
746 kap[
"motor_inertia"] = stringMotorInertia;
747 kap[
"back_drivable"] = stringBackDrivable;
748 kap[
"history"] = stringHistory;
749 kap[
"max_tension"] = stringMaxTension;
750 kap[
"target_velocity"] = stringTargetVelocity;
751 kap[
"min_actual_length"] = stringMinActualLength;
752 kap[
"min_rest_length"] = stringMinRestLength;
753 kap[
"rotation"] = stringRotation;
756 for (YAML::const_iterator parameter = parameters.begin(); parameter != parameters.end(); ++parameter) {
757 std::string parameterName = parameter->first.as<std::string>();
758 if (kap.find(parameterName) == kap.end()) {
759 throw std::invalid_argument(
"Unsupported " + builderClass +
" parameter: " + parameterName);
762 kap[parameterName] = parameter->second.as<
double>();
768 kap[
"motor_friction"], kap[
"motor_inertia"], kap[
"back_drivable"], kap[
"history"], kap[
"max_tension"],
769 kap[
"target_velocity"],kap[
"min_actual_length"], kap[
"min_rest_length"], kap[
"rotation"]);
770 if (builderClass ==
"tgKinematicContactCableInfo") {
774 else if (builderClass ==
"tgKinematicActuatorInfo") {
781 void TensegrityModel::addBoxBuilder(
const std::string& builderClass,
const std::string& tagMatch,
const Yam& parameters,
tgBuildSpec& spec) {
798 std::map<std::string, double> bp;
799 bp[
"width"] = boxWidth;
800 bp[
"height"] = boxHeight;
801 bp[
"density"] = boxDensity;
802 bp[
"friction"] = boxFriction;
803 bp[
"roll_friction"] = boxRollFriction;
804 bp[
"restitution"] = boxRestitution;
807 for (YAML::const_iterator parameter = parameters.begin(); parameter != parameters.end(); ++parameter) {
808 std::string parameterName = parameter->first.as<std::string>();
809 if (bp.find(parameterName) == bp.end()) {
810 throw std::invalid_argument(
"Unsupported " + builderClass +
" parameter: " + parameterName);
813 bp[parameterName] = parameter->second.as<
double>();
820 bp[
"density"], bp[
"friction"], bp[
"roll_friction"], bp[
"restitution"]);
821 if (builderClass ==
"tgBoxInfo") {
823 spec.addBuilder(tagMatch,
new tgBoxInfo(boxConfig));
827 void TensegrityModel::addSphereBuilder(
const std::string& builderClass,
const std::string& tagMatch,
const Yam& parameters,
tgBuildSpec& spec){
843 std::map<std::string, double> sp;
844 sp[
"radius"] = sphereRadius;
845 sp[
"density"] = sphereDensity;
846 sp[
"friction"] = sphereFriction;
847 sp[
"roll_friction"] = sphereRollFriction;
848 sp[
"restitution"] = sphereRestitution;
852 for (YAML::const_iterator parameter = parameters.begin(); parameter != parameters.end(); ++parameter) {
853 std::string parameterName = parameter->first.as<std::string>();
854 if (sp.find(parameterName) == sp.end()) {
855 throw std::invalid_argument(
"Unsupported " + builderClass +
" parameter: " + parameterName);
858 sp[parameterName] = parameter->second.as<
double>();
873 sp[
"density"], sp[
"friction"], sp[
"roll_friction"], sp[
"restitution"]);
874 if (builderClass ==
"tgSphereInfo") {
876 spec.addBuilder(tagMatch,
new tgSphereInfo(sphereConfig));
881 void TensegrityModel::yamlNoDuplicates(
const Yam& yam,
const std::string structurePath) {
882 std::set<std::string> keys;
883 for (YAML::const_iterator iter = yam.begin(); iter != yam.end(); ++iter) {
884 Yam child = iter->second;
885 if (child.Type() == YAML::NodeType::Map) {
886 yamlNoDuplicates(child, structurePath);
888 std::string keyName = iter->first.as<std::string>();
889 if (keys.find(keyName) == keys.end()) {
890 keys.insert(keyName);
893 throw std::invalid_argument(structurePath.substr(structurePath.rfind(
"/") + 1) +
" contains duplicate key: " + keyName);
898 void TensegrityModel::yamlContainsOnly(
const Yam& yam,
const std::string structurePath,
const std::vector<std::string> keys) {
899 for (YAML::const_iterator key = yam.begin(); key != yam.end(); ++key) {
900 std::string keyName = key->first.as<std::string>();
901 if (std::find(keys.begin(), keys.end(), keyName) == keys.end()) {
902 throw std::invalid_argument(structurePath.substr(structurePath.rfind(
"/") + 1) +
" contains invalid key: " + keyName);
908 if (timeStep <= 0.0) {
909 throw std::invalid_argument(
"time step is not positive");
tgStructure & findChild(const std::string &name)
static btQuaternion getQuaternionBetween(btVector3 a, btVector3 b, const btVector3 &fallbackAxis=btVector3(0, 0, 0))
tgNode & findNode(const std::string &name)
Create a box shape as an obstacle or add it to your tensegrity.
virtual void setup(tgWorld &world)
void addChild(tgStructure *child)
Definition of class tgRodInfo.
Definition of class tgSphereInfo.
TensegrityModel(const std::string &structurePath)
static const double rodRadius
virtual void onVisit(tgModelVisitor &visitor)
virtual void step(double timeStep)
Contains the definition of class tgSphere.
virtual void step(double dt)
btVector3 getCentroid() const
static double deg2rad(double degrees)
Definition of class tgBasicActuatorInfo.
virtual void onVisit(const tgModelVisitor &r) const
Class that interfaces with Bullet to build the boxes.
const std::vector< tgSpringCableActuator * > & getAllActuators() const
void addPair(int fromNodeIdx, int toNodeIdx, std::string tags="")
static btVector3 getCentroid(const std::vector< btVector3 > &points)
void addRotation(const btVector3 &fixedPoint, const btVector3 &axis, double angle)
virtual void setup(tgWorld &world)
Contains the definition of class tgBasicActuator.
const bool matches(const tgTags &tags) const
Definition of class tgStructureInfo.
Contains the definition of class tgKinematicActuator.
tgPair & findPair(const btVector3 &from, const btVector3 &to)
virtual ~TensegrityModel()
Definition of class tgKinematicActuatorInfo.
Contains the definition of class tgRod.
static void addRotation(btVector3 &v, const btVector3 &fixedPoint, const btVector3 &axis, double angle)
void notifyStep(double dt)
std::vector< tgModel * > getDescendants() const
void buildInto(tgModel &model, tgWorld &world)
void addNode(double x, double y, double z, std::string tags="")