Add mjmBodyPair to C API.
PiperOrigin-RevId: 606997065 Change-Id: Iefc2dff6ae942ce93ca83ec5f5fe9d7ae8bb6a40
This commit is contained in:
committed by
Copybara-Service
parent
c9e7586499
commit
80a986c0f5
@@ -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
|
// add equality to model
|
||||||
mjmEquality* mjm_addEquality(void* model, void* defspec) {
|
mjmEquality* mjm_addEquality(void* model, void* defspec) {
|
||||||
mjCModel* modelC = static_cast<mjCModel*>(model);
|
mjCModel* modelC = static_cast<mjCModel*>(model);
|
||||||
|
|||||||
@@ -428,6 +428,15 @@ typedef struct _mjmPair {
|
|||||||
} 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
|
typedef struct _mjmEquality { // equality specification
|
||||||
mjElement element; // internal, do not modify
|
mjElement element; // internal, do not modify
|
||||||
mjString name; // name
|
mjString name; // name
|
||||||
@@ -648,6 +657,9 @@ MJAPI mjmMaterial* mjm_addMaterial(void* model, void* defspec);
|
|||||||
// Add pair to model.
|
// Add pair to model.
|
||||||
MJAPI mjmPair* mjm_addPair(void* model, void* defspec);
|
MJAPI mjmPair* mjm_addPair(void* model, void* defspec);
|
||||||
|
|
||||||
|
// Add excluded body pair to model.
|
||||||
|
MJAPI mjmExclude* mjm_addExclude(void *model);
|
||||||
|
|
||||||
// Add equality to model.
|
// Add equality to model.
|
||||||
MJAPI mjmEquality* mjm_addEquality(void* model, void* defspec);
|
MJAPI mjmEquality* mjm_addEquality(void* model, void* defspec);
|
||||||
|
|
||||||
|
|||||||
@@ -864,9 +864,9 @@ mjmBody* mjCComposite::AddCableBody(mjCModel* model, mjmBody* body, int ix, mjtN
|
|||||||
|
|
||||||
// exclude contact pair
|
// exclude contact pair
|
||||||
if (!last) {
|
if (!last) {
|
||||||
mjCBodyPair* exclude = model->AddExclude();
|
mjmExclude* exclude = mjm_addExclude(model);
|
||||||
exclude->bodyname1 = this_body;
|
mjm_setString(exclude->bodyname1, std::string(this_body).c_str());
|
||||||
exclude->bodyname2 = next_body;
|
mjm_setString(exclude->bodyname2, std::string(next_body).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
// add site at the boundary
|
// 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);
|
mju_copy(eq->solimp, solimpsmooth, mjNIMP);
|
||||||
|
|
||||||
// remove contact between connected bodies
|
// remove contact between connected bodies
|
||||||
mjCBodyPair* pair = model->AddExclude();
|
mjmExclude* pair = mjm_addExclude(model);
|
||||||
pair->bodyname1 = txt;
|
mjm_setString(pair->bodyname1, std::string(txt).c_str());
|
||||||
pair->bodyname2 = txt2;
|
mjm_setString(pair->bodyname2, std::string(txt2).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -3585,34 +3585,59 @@ mjCBodyPair::mjCBodyPair(mjCModel* _model) {
|
|||||||
model = _model;
|
model = _model;
|
||||||
|
|
||||||
// set defaults
|
// set defaults
|
||||||
bodyname1.clear();
|
spec_bodyname1_.clear();
|
||||||
bodyname2.clear();
|
spec_bodyname2_.clear();
|
||||||
|
|
||||||
// clear internal variables
|
// clear internal variables
|
||||||
body1 = body2 = signature = -1;
|
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
|
// compiler
|
||||||
void mjCBodyPair::Compile(void) {
|
void mjCBodyPair::Compile(void) {
|
||||||
|
CopyFromSpec();
|
||||||
|
|
||||||
// find body 1
|
// find body 1
|
||||||
mjCBody* pb1 = (mjCBody*)model->FindObject(mjOBJ_BODY, bodyname1);
|
mjCBody* pb1 = (mjCBody*)model->FindObject(mjOBJ_BODY, bodyname1_);
|
||||||
if (!pb1) {
|
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
|
// find body 2
|
||||||
mjCBody* pb2 = (mjCBody*)model->FindObject(mjOBJ_BODY, bodyname2);
|
mjCBody* pb2 = (mjCBody*)model->FindObject(mjOBJ_BODY, bodyname2_);
|
||||||
if (!pb2) {
|
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
|
// swap if body1 > body2
|
||||||
if (pb1->id > pb2->id) {
|
if (pb1->id > pb2->id) {
|
||||||
string nametmp = bodyname1;
|
string nametmp = bodyname1_;
|
||||||
bodyname1 = bodyname2;
|
bodyname1_ = bodyname2_;
|
||||||
bodyname2 = nametmp;
|
bodyname2_ = nametmp;
|
||||||
|
|
||||||
mjCBody* bodytmp = pb1;
|
mjCBody* bodytmp = pb1;
|
||||||
pb1 = pb2;
|
pb1 = pb2;
|
||||||
|
|||||||
+20
-9
@@ -984,26 +984,37 @@ class mjCPair : public mjCBase, private mjmPair {
|
|||||||
//------------------------- class mjCBodyPair ------------------------------------------------------
|
//------------------------- class mjCBodyPair ------------------------------------------------------
|
||||||
// Body pair specification, use to exclude pairs
|
// Body pair specification, use to exclude pairs
|
||||||
|
|
||||||
class mjCBodyPair : public mjCBase {
|
class mjCBodyPair : public mjCBase, private mjmExclude {
|
||||||
friend class mjCBody;
|
friend class mjCBody;
|
||||||
friend class mjCModel;
|
friend class mjCModel;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// parameters set by user
|
mjmExclude spec;
|
||||||
std::string bodyname1; // name of geom 1
|
using mjCBase::name;
|
||||||
std::string bodyname2; // name of geom 2
|
using mjCBase::info;
|
||||||
|
|
||||||
|
void CopyFromSpec();
|
||||||
|
void PointToLocal();
|
||||||
|
|
||||||
|
std::string get_bodyname1() const { return bodyname1_; }
|
||||||
|
std::string get_bodyname2() const { return bodyname2_; }
|
||||||
|
|
||||||
int GetSignature(void) {
|
int GetSignature(void) {
|
||||||
return signature;
|
return signature;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
mjCBodyPair(mjCModel*); // constructor
|
mjCBodyPair(mjCModel*); // constructor
|
||||||
void Compile(void); // compiler
|
void Compile(void); // compiler
|
||||||
|
|
||||||
int body1; // id of body1
|
int body1; // id of body1
|
||||||
int body2; // id of body2
|
int body2; // id of body2
|
||||||
int signature; // body1<<16 + 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_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -3424,13 +3424,20 @@ void mjXReader::Contact(XMLElement* section) {
|
|||||||
|
|
||||||
// body pair to exclude
|
// body pair to exclude
|
||||||
else if (name=="exclude") {
|
else if (name=="exclude") {
|
||||||
mjCBodyPair* pexclude = model->AddExclude();
|
mjmExclude* pexclude = mjm_addExclude(model);
|
||||||
GetXMLPos(elem, pexclude);
|
string exname, exbody1, exbody2;
|
||||||
|
|
||||||
|
// write error info
|
||||||
|
mjm_setString(pexclude->info, ("line = " + std::to_string(elem->GetLineNum())).c_str());
|
||||||
|
|
||||||
// read name and body names
|
// read name and body names
|
||||||
ReadAttrTxt(elem, "name", pexclude->name);
|
if (ReadAttrTxt(elem, "name", exname)) {
|
||||||
ReadAttrTxt(elem, "body1", pexclude->bodyname1, true);
|
mjm_setString(pexclude->name, exname.c_str());
|
||||||
ReadAttrTxt(elem, "body2", pexclude->bodyname2, true);
|
}
|
||||||
|
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
|
// advance to next element
|
||||||
|
|||||||
@@ -1543,8 +1543,8 @@ void mjXWriter::Contact(XMLElement* root) {
|
|||||||
|
|
||||||
// write attributes
|
// write attributes
|
||||||
WriteAttrTxt(elem, "name", pexclude->name);
|
WriteAttrTxt(elem, "name", pexclude->name);
|
||||||
WriteAttrTxt(elem, "body1", pexclude->bodyname1);
|
WriteAttrTxt(elem, "body1", pexclude->get_bodyname1());
|
||||||
WriteAttrTxt(elem, "body2", pexclude->bodyname2);
|
WriteAttrTxt(elem, "body2", pexclude->get_bodyname2());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user