Add mjmBodyPair to C API.

PiperOrigin-RevId: 606997065
Change-Id: Iefc2dff6ae942ce93ca83ec5f5fe9d7ae8bb6a40
This commit is contained in:
Alessio Quaglino
2024-02-14 08:39:01 -08:00
committed by Copybara-Service
parent c9e7586499
commit 80a986c0f5
7 changed files with 95 additions and 31 deletions
+9
View File
@@ -185,6 +185,15 @@ mjmPair* mjm_addPair(void* model, void* defspec) {
// add pair exclusion to model
mjmExclude* mjm_addExclude(void* model) {
mjCModel* modelC = static_cast<mjCModel*>(model);
mjCBodyPair* bodypair = modelC->AddExclude();
return &bodypair->spec;
}
// add equality to model
mjmEquality* mjm_addEquality(void* model, void* defspec) {
mjCModel* modelC = static_cast<mjCModel*>(model);
+12
View File
@@ -428,6 +428,15 @@ typedef struct _mjmPair {
} mjmPair;
typedef struct _mjmExclude {
mjElement element; // internal, do not modify
mjString name; // name
mjString bodyname1; // name of geom 1
mjString bodyname2; // name of geom 2
mjString info; // message appended to errors
} mjmExclude;
typedef struct _mjmEquality { // equality specification
mjElement element; // internal, do not modify
mjString name; // name
@@ -648,6 +657,9 @@ MJAPI mjmMaterial* mjm_addMaterial(void* model, void* defspec);
// Add pair to model.
MJAPI mjmPair* mjm_addPair(void* model, void* defspec);
// Add excluded body pair to model.
MJAPI mjmExclude* mjm_addExclude(void *model);
// Add equality to model.
MJAPI mjmEquality* mjm_addEquality(void* model, void* defspec);
+6 -6
View File
@@ -864,9 +864,9 @@ mjmBody* mjCComposite::AddCableBody(mjCModel* model, mjmBody* body, int ix, mjtN
// exclude contact pair
if (!last) {
mjCBodyPair* exclude = model->AddExclude();
exclude->bodyname1 = this_body;
exclude->bodyname2 = next_body;
mjmExclude* exclude = mjm_addExclude(model);
mjm_setString(exclude->bodyname1, std::string(this_body).c_str());
mjm_setString(exclude->bodyname2, std::string(next_body).c_str());
}
// add site at the boundary
@@ -939,9 +939,9 @@ bool mjCComposite::MakeRope(mjCModel* model, mjmBody* body, char* error, int err
mju_copy(eq->solimp, solimpsmooth, mjNIMP);
// remove contact between connected bodies
mjCBodyPair* pair = model->AddExclude();
pair->bodyname1 = txt;
pair->bodyname2 = txt2;
mjmExclude* pair = mjm_addExclude(model);
mjm_setString(pair->bodyname1, std::string(txt).c_str());
mjm_setString(pair->bodyname2, std::string(txt2).c_str());
}
return true;
+34 -9
View File
@@ -3585,34 +3585,59 @@ mjCBodyPair::mjCBodyPair(mjCModel* _model) {
model = _model;
// set defaults
bodyname1.clear();
bodyname2.clear();
spec_bodyname1_.clear();
spec_bodyname2_.clear();
// clear internal variables
body1 = body2 = signature = -1;
PointToLocal();
CopyFromSpec();
}
void mjCBodyPair::PointToLocal() {
spec.element = (mjElement)this;
spec.name = (mjString)&name;
spec.bodyname1 = (mjString)&spec_bodyname1_;
spec.bodyname2 = (mjString)&spec_bodyname2_;
spec.info = (mjString)&info;
}
void mjCBodyPair::CopyFromSpec() {
*static_cast<mjmExclude*>(this) = spec;
bodyname1_ = spec_bodyname1_;
bodyname2_ = spec_bodyname2_;
bodyname1 = (mjString)&bodyname1_;
bodyname2 = (mjString)&bodyname2_;
}
// compiler
void mjCBodyPair::Compile(void) {
CopyFromSpec();
// find body 1
mjCBody* pb1 = (mjCBody*)model->FindObject(mjOBJ_BODY, bodyname1);
mjCBody* pb1 = (mjCBody*)model->FindObject(mjOBJ_BODY, bodyname1_);
if (!pb1) {
throw mjCError(this, "body '%s' not found in bodypair %d", bodyname1.c_str(), id);
throw mjCError(this, "body '%s' not found in bodypair %d", bodyname1_.c_str(), id);
}
// find body 2
mjCBody* pb2 = (mjCBody*)model->FindObject(mjOBJ_BODY, bodyname2);
mjCBody* pb2 = (mjCBody*)model->FindObject(mjOBJ_BODY, bodyname2_);
if (!pb2) {
throw mjCError(this, "body '%s' not found in bodypair %d", bodyname2.c_str(), id);
throw mjCError(this, "body '%s' not found in bodypair %d", bodyname2_.c_str(), id);
}
// swap if body1 > body2
if (pb1->id > pb2->id) {
string nametmp = bodyname1;
bodyname1 = bodyname2;
bodyname2 = nametmp;
string nametmp = bodyname1_;
bodyname1_ = bodyname2_;
bodyname2_ = nametmp;
mjCBody* bodytmp = pb1;
pb1 = pb2;
+20 -9
View File
@@ -984,26 +984,37 @@ class mjCPair : public mjCBase, private mjmPair {
//------------------------- class mjCBodyPair ------------------------------------------------------
// Body pair specification, use to exclude pairs
class mjCBodyPair : public mjCBase {
class mjCBodyPair : public mjCBase, private mjmExclude {
friend class mjCBody;
friend class mjCModel;
public:
// parameters set by user
std::string bodyname1; // name of geom 1
std::string bodyname2; // name of geom 2
mjmExclude spec;
using mjCBase::name;
using mjCBase::info;
void CopyFromSpec();
void PointToLocal();
std::string get_bodyname1() const { return bodyname1_; }
std::string get_bodyname2() const { return bodyname2_; }
int GetSignature(void) {
return signature;
}
private:
mjCBodyPair(mjCModel*); // constructor
void Compile(void); // compiler
mjCBodyPair(mjCModel*); // constructor
void Compile(void); // compiler
int body1; // id of body1
int body2; // id of body2
int signature; // body1<<16 + body2
int body1; // id of body1
int body2; // id of body2
int signature; // body1<<16 + body2
std::string bodyname1_; // name of geom 1
std::string bodyname2_; // name of geom 2
std::string spec_bodyname1_;
std::string spec_bodyname2_;
};
+12 -5
View File
@@ -3424,13 +3424,20 @@ void mjXReader::Contact(XMLElement* section) {
// body pair to exclude
else if (name=="exclude") {
mjCBodyPair* pexclude = model->AddExclude();
GetXMLPos(elem, pexclude);
mjmExclude* pexclude = mjm_addExclude(model);
string exname, exbody1, exbody2;
// write error info
mjm_setString(pexclude->info, ("line = " + std::to_string(elem->GetLineNum())).c_str());
// read name and body names
ReadAttrTxt(elem, "name", pexclude->name);
ReadAttrTxt(elem, "body1", pexclude->bodyname1, true);
ReadAttrTxt(elem, "body2", pexclude->bodyname2, true);
if (ReadAttrTxt(elem, "name", exname)) {
mjm_setString(pexclude->name, exname.c_str());
}
ReadAttrTxt(elem, "body1", exbody1, true);
mjm_setString(pexclude->bodyname1, exbody1.c_str());
ReadAttrTxt(elem, "body2", exbody2, true);
mjm_setString(pexclude->bodyname2, exbody2.c_str());
}
// advance to next element
+2 -2
View File
@@ -1543,8 +1543,8 @@ void mjXWriter::Contact(XMLElement* root) {
// write attributes
WriteAttrTxt(elem, "name", pexclude->name);
WriteAttrTxt(elem, "body1", pexclude->bodyname1);
WriteAttrTxt(elem, "body2", pexclude->bodyname2);
WriteAttrTxt(elem, "body1", pexclude->get_bodyname1());
WriteAttrTxt(elem, "body2", pexclude->get_bodyname2());
}
}