コード例 #1
0
void rigidBodyConstraintParseQuat(const mxArray* pm, Vector4d &quat)
{
  if(!mxIsNumeric(pm))
  {
    mexErrMsgIdAndTxt("Drake:rigidBodyConstraintParseQuat:BadInputs","The input argument 1 should be a 4x1 double vector");
  }
  if(!(mxGetM(pm) == 4 && mxGetN(pm) == 1))
  {
    mexErrMsgIdAndTxt("Drake:rigidBodyConstraintParseQuat:BadInputs","The input argument 1 should be of size 4x1");
  }
  memcpy(quat.data(),mxGetPr(pm),sizeof(double)*4);
  for(int i = 0;i<4;i++)
  {
    if((mxIsInf(quat(i)))||(mxIsNaN(quat(i))))
    {
      mexErrMsgIdAndTxt("Drake:rigidBodyConstraintParseQuat:BadInputs","The input argument 1 cannot have entry equal to NaN or Inf");
    }
  }
  double quat_norm = quat.norm();
  if(quat_norm==0.0)
  {
    mexErrMsgIdAndTxt("Drake:rigidBodyConstraintParseQuat:BadInputs","The Input argument 1 must be a nonzero vector");
  }
  quat = quat/quat_norm;
}
コード例 #2
0
ファイル: testQuatmex.cpp プロジェクト: AkshayBabbar/drake
void mexFunction(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
{
  if(nrhs != 5)
  {
    mexErrMsgIdAndTxt("Drake:testQuatmex:BadInputs","Usage [r,dr,e,ed,quat,dquat,q3,dq3,w,dw] = testQuatmex(q1,q2,axis,u,v)");
  }
  Vector4d q1;
  Vector4d q2;
  memcpy(q1.data(),mxGetPr(prhs[0]),sizeof(double)*4);
  memcpy(q2.data(),mxGetPr(prhs[1]),sizeof(double)*4);
  Vector4d r = quatDiff(q1,q2);
  Matrix<double,4,8> dr = dquatDiff(q1,q2);

  plhs[0] = mxCreateDoubleMatrix(4,1,mxREAL);
  plhs[1] = mxCreateDoubleMatrix(4,8,mxREAL);
  memcpy(mxGetPr(plhs[0]),r.data(),sizeof(double)*4);
  memcpy(mxGetPr(plhs[1]),dr.data(),sizeof(double)*4*8);

  Vector3d axis;
  memcpy(axis.data(),mxGetPr(prhs[2]),sizeof(double)*3);
  double e = quatDiffAxisInvar(q1,q2,axis);
  Matrix<double,1,11> de = dquatDiffAxisInvar(q1,q2,axis);
  plhs[2] = mxCreateDoubleScalar(e);
  plhs[3] = mxCreateDoubleMatrix(1,11,mxREAL);
  memcpy(mxGetPr(plhs[3]),de.data(),sizeof(double)*11);

  Vector3d u,v;
  Vector4d quat;
  Matrix<double,4,6> dquat;
  memcpy(u.data(),mxGetPr(prhs[3]),sizeof(double)*3);
  memcpy(v.data(),mxGetPr(prhs[4]),sizeof(double)*3);

  Vector4d q3 = quatProduct(q1,q2);
  Matrix<double,4,8> dq3 = dquatProduct(q1,q2);

  plhs[4] = mxCreateDoubleMatrix(4,1,mxREAL);
  plhs[5] = mxCreateDoubleMatrix(4,8,mxREAL);
  memcpy(mxGetPr(plhs[4]),q3.data(),sizeof(double)*4);
  memcpy(mxGetPr(plhs[5]),dq3.data(),sizeof(double)*4*8);

  Vector3d w = quatRotateVec(q1,u);
  Matrix<double,3,7> dw = dquatRotateVec(q1,u);

  plhs[6] = mxCreateDoubleMatrix(3,1,mxREAL);
  plhs[7] = mxCreateDoubleMatrix(3,7,mxREAL);
  memcpy(mxGetPr(plhs[6]),w.data(),sizeof(double)*3);
  memcpy(mxGetPr(plhs[7]),dw.data(),sizeof(double)*3*7);
}
コード例 #3
0
ファイル: curveplot.cpp プロジェクト: nisselarsson/Celestia
    inline void vertex(const Vector4d& v)
    {
#if USE_VERTEX_BUFFER
        data[currentPosition++] = v.cast<float>();
        ++currentStripLength;
        if (currentPosition == capacity)
        {
            flush();

            data[0] = v.cast<float>();
            currentPosition = 1;
            currentStripLength = 1;
        }
#else
        glVertex3dv(v.data());
#endif
    }
コード例 #4
0
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
  if(!mxIsNumeric(prhs[0]))
  {
    mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","prhs[0] should be the constraint type");
  }
  int constraint_type = (int) mxGetScalar(prhs[0]);
  switch(constraint_type)
  {
    // QuasiStaticConstraint
    case RigidBodyConstraint::QuasiStaticConstraintType:
      {
        if(nrhs != 2 && nrhs!= 3 && nrhs != 4)
        {
          mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","Usage ptr = constructPtrPtrRigidBodyConstraintmex(RigidBodyConstraint::QuasiStaticConstraintType,robot_ptr,tspan,robotnum)");
        }
        RigidBodyManipulator* model = (RigidBodyManipulator*) getDrakeMexPointer(prhs[1]);
        Vector2d tspan;
        int* robotnum;
        int num_robot;
        if(nrhs <= 3)
        {
          num_robot = 1;
          robotnum = new int[num_robot];
          robotnum[0] = 0;
        }
        else
        {
          num_robot = mxGetNumberOfElements(prhs[3]);
          double* robotnum_tmp = new double[num_robot];
          robotnum = new int[num_robot];
          memcpy(robotnum_tmp,mxGetPr(prhs[3]),sizeof(double)*num_robot);
          for(int i = 0;i<num_robot;i++)
          {
            robotnum[i] = (int) robotnum_tmp[i]-1;
          }
          delete[] robotnum_tmp;
        }
        if(nrhs<=2)
        {
          tspan<<-mxGetInf(),mxGetInf();
        }
        else
        {
          rigidBodyConstraintParseTspan(prhs[2],tspan);
        }
        set<int> robotnumset(robotnum,robotnum+num_robot);
        QuasiStaticConstraint* cnst = new QuasiStaticConstraint(model,tspan,robotnumset);
        plhs[0] = createDrakeConstraintMexPointer((void*) cnst,"deleteRigidBodyConstraintmex","QuasiStaticConstraint");
        delete[] robotnum;
      }
      break;
    // PostureConstraint
    case RigidBodyConstraint::PostureConstraintType:
      {
        if(nrhs != 2 && nrhs != 3)
        {
          mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","Usage ptr = constructPtrRigidBodyConstraintmex(RigidBodyConstraint::PostureConstraintType,robot.mex_model_ptr,tspan)");
        }
        Vector2d tspan;
        if(nrhs == 2)
        {
          tspan<<-mxGetInf(),mxGetInf();
        }
        else
        {
          rigidBodyConstraintParseTspan(prhs[2],tspan);
        }
        RigidBodyManipulator* robot = (RigidBodyManipulator*) getDrakeMexPointer(prhs[1]);
        PostureConstraint* cnst = new PostureConstraint(robot,tspan);
        plhs[0] = createDrakeConstraintMexPointer((void*)cnst,"deleteRigidBodyConstraintmex","PostureConstraint");
      }
      break;
      // SingleTimeLinearPostureConstraint
    case RigidBodyConstraint::SingleTimeLinearPostureConstraintType:
      {
        if(nrhs != 7 && nrhs != 8)
        {
          mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","Usage ptr = constructPtrRigidBodyConstraintmex(RigidBodyConstraint::SingleTimeLinearPostureConstraintType,robot.mex_model_ptr,iAfun,jAvar,A,lb,ub,tspan");
        }
        RigidBodyManipulator* model = (RigidBodyManipulator*) getDrakeMexPointer(prhs[1]);
        Vector2d tspan;
        if(nrhs<=7)
        {
          tspan<<-mxGetInf(),mxGetInf();
        }
        else
        {
          rigidBodyConstraintParseTspan(prhs[7],tspan);
        }
        if(!mxIsNumeric(prhs[2]) || !mxIsNumeric(prhs[3]) || !mxIsNumeric(prhs[4]))
        {
          mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","iAfun, jAvar and A must be numeric");
        }
        int lenA = mxGetM(prhs[2]);
        if(mxGetM(prhs[3]) != lenA || mxGetM(prhs[4]) != lenA || mxGetN(prhs[2]) != 1 || mxGetN(prhs[3]) != 1 || mxGetN(prhs[4]) != 1)
        {
          mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","iAfun,jAvar,A must be column vectors of the same size");
        }
        VectorXi iAfun(lenA);
        VectorXi jAvar(lenA);
        VectorXd A(lenA);
        for(int i = 0;i<lenA;i++)
        {
          iAfun(i) = (int) *(mxGetPr(prhs[2])+i)-1;
          jAvar(i) = (int) *(mxGetPr(prhs[3])+i)-1;
          A(i) = *(mxGetPr(prhs[4])+i);
        }
        if(!mxIsNumeric(prhs[5]) || !mxIsNumeric(prhs[6]) || mxGetM(prhs[5]) != mxGetM(prhs[6]) || mxGetN(prhs[5]) != 1 || mxGetN(prhs[6]) != 1)
        {
          mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","lb and ub must be numeric column vectors of the same size");
        }
        int num_constraint = mxGetM(prhs[5]);
        VectorXd lb(num_constraint);
        VectorXd ub(num_constraint);
        memcpy(lb.data(),mxGetPr(prhs[5]),sizeof(double)*num_constraint);
        memcpy(ub.data(),mxGetPr(prhs[6]),sizeof(double)*num_constraint);
        SingleTimeLinearPostureConstraint* cnst = new SingleTimeLinearPostureConstraint(model,iAfun,jAvar,A,lb,ub,tspan);
        plhs[0] = createDrakeConstraintMexPointer((void*)cnst,"deleteRigidBodyConstraintmex","SingleTimeLinearPostureConstraint");
      }
      break;
      // AllBodiesClosestDistanceConstraint
    case RigidBodyConstraint::AllBodiesClosestDistanceConstraintType:
      {
        //DEBUG
        //cout << "nrhs = " << nrhs << endl;
        //END_DEBUG
        if(nrhs != 5 && nrhs != 6)
        {
          mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs",
              "Usage ptr = constructPtrRigidBodyConstraintmex(RigidBodyConstraint::AllBodiesClosestDistanceConstraintType, robot.mex_model_ptr,lb,ub,active_collision_options,tspan)");
        }
        RigidBodyManipulator* model = (RigidBodyManipulator*) getDrakeMexPointer(prhs[1]);
        Vector2d tspan;
        if(nrhs == 5)
        {
          tspan<< -mxGetInf(), mxGetInf();
        }
        else
        {
          rigidBodyConstraintParseTspan(prhs[5],tspan);
        }

        double lb = (double) mxGetScalar(prhs[2]);
        double ub = (double) mxGetScalar(prhs[3]);

        // Parse `active_collision_options`
        vector<int> active_bodies_idx;
        set<string> active_group_names;
        // First get the list of body indices for which to compute distances
        const mxArray* active_collision_options = prhs[4];
        const mxArray* body_idx = mxGetField(active_collision_options,0,"body_idx");
        if (body_idx != NULL) {
          //DEBUG
          //cout << "collisionDetectmex: Received body_idx" << endl;
          //END_DEBUG
          int n_active_bodies = mxGetNumberOfElements(body_idx);
          //DEBUG
          //cout << "collisionDetectmex: n_active_bodies = " << n_active_bodies << endl;
          //END_DEBUG
          active_bodies_idx.resize(n_active_bodies);
          memcpy(active_bodies_idx.data(),(int*) mxGetData(body_idx),
              sizeof(int)*n_active_bodies);
          transform(active_bodies_idx.begin(),active_bodies_idx.end(),
              active_bodies_idx.begin(),
              [](int i){return --i;});
        }

        // Then get the group names for which to compute distances
        const mxArray* collision_groups = mxGetField(active_collision_options,0,
            "collision_groups");
        if (collision_groups != NULL) {
          for (const string& str : get_strings(collision_groups)) {
            active_group_names.insert(str);
          }
        }

        auto cnst = new AllBodiesClosestDistanceConstraint(model,lb,ub,
            active_bodies_idx,active_group_names,tspan);
        plhs[0] = createDrakeConstraintMexPointer((void*)cnst,"deleteRigidBodyConstraintmex",
                                        "AllBodiesClosestDistanceConstraint");
      }
      break;
      // WorldEulerConstraint
    case RigidBodyConstraint::WorldEulerConstraintType:
      {
        if(nrhs != 6 && nrhs != 5)
        {
          mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","Usage ptr = constructPtrRigidBodyConstraintmex(RigidBodyConstraint::WorldEulerConstraintType,robot.mex_model_ptr,body,lb,ub,tspan)");
        }
        RigidBodyManipulator* model = (RigidBodyManipulator*) getDrakeMexPointer(prhs[1]);
        WorldEulerConstraint* cnst = nullptr;
        Vector2d tspan;
        if(nrhs == 5)
        {
          tspan<< -mxGetInf(), mxGetInf();
        }
        else
        {
          rigidBodyConstraintParseTspan(prhs[5],tspan);
        }
        if(!mxIsNumeric(prhs[2]))
        {
          mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","body must be numeric");
        }
        int body = (int) mxGetScalar(prhs[2])-1;
        checkBodyOrFrameID(body, model);

        if(mxGetM(prhs[3]) != 3 || mxGetM(prhs[4]) != 3 || mxGetN(prhs[3]) != 1 || mxGetN(prhs[4]) != 1)
        {
          mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","lb and ub should both be 3x1 double vectors");
        }
        Vector3d lb;
        Vector3d ub;
        memcpy(lb.data(),mxGetPr(prhs[3]),sizeof(double)*3);
        memcpy(ub.data(),mxGetPr(prhs[4]),sizeof(double)*3);
        cnst = new WorldEulerConstraint(model,body,lb,ub,tspan);
        plhs[0] = createDrakeConstraintMexPointer((void*)cnst,"deleteRigidBodyConstraintmex","WorldEulerConstraint");
      }
      break;
    // WorldGazeDirConstraint
    case RigidBodyConstraint::WorldGazeDirConstraintType:
      {
        if(nrhs != 7 && nrhs != 6)
        {  
          mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","Usage ptr = constructPtrRigidBodyConstraintmex(RigidBodyConstraint::WorldGazeDirConstraintType,robot.mex_model_ptr,body,axis,dir,conethreshold,tspan)");
        }
        RigidBodyManipulator* model = (RigidBodyManipulator*) getDrakeMexPointer(prhs[1]);
        WorldGazeDirConstraint* cnst = nullptr;
        Vector2d tspan;
        if(nrhs == 6)
        {
          tspan<< -mxGetInf(), mxGetInf();
        }
        else
        {
          rigidBodyConstraintParseTspan(prhs[6],tspan);
        }
        if(!mxIsNumeric(prhs[2]))
        {
          mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","body must be numeric");
        }
        int body = (int) mxGetScalar(prhs[2])-1;
        checkBodyOrFrameID(body, model);
        Vector3d axis;
        rigidBodyConstraintParse3dUnitVector(prhs[3], axis);
        Vector3d dir;
        rigidBodyConstraintParse3dUnitVector(prhs[4],dir);
        double conethreshold = rigidBodyConstraintParseGazeConethreshold(prhs[5]); 
        cnst = new WorldGazeDirConstraint(model,body,axis,dir,conethreshold,tspan);
        plhs[0] = createDrakeConstraintMexPointer((void*)cnst, "deleteRigidBodyConstraintmex","WorldGazeDirConstraint");
      }
      break;
    // WorldGazeOrientConstraint
    case RigidBodyConstraint::WorldGazeOrientConstraintType:
      {
        if(nrhs != 7 && nrhs != 8)
        {  
          mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","Usage ptr = constructPtrRigidBodyConstraintmex(RigidBodyConstraint::WorldGazeOrientConstraintType, robot.mex_model_ptr,body,axis,quat_des,conethreshold,threshold,tspan)");
        }
        RigidBodyManipulator* model = (RigidBodyManipulator*) getDrakeMexPointer(prhs[1]);
        WorldGazeOrientConstraint* cnst = nullptr;
        Vector2d tspan;
        if(nrhs == 7)
        {
          tspan<< -mxGetInf(), mxGetInf();
        }
        else
        {
          rigidBodyConstraintParseTspan(prhs[7],tspan);
        }
        if(!mxIsNumeric(prhs[2]))
        {
          mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","body must be numeric");
        }
        int body = (int) mxGetScalar(prhs[2])-1;
        checkBodyOrFrameID(body, model);
        Vector3d axis;
        rigidBodyConstraintParse3dUnitVector(prhs[3],axis);
        Vector4d quat_des;
        rigidBodyConstraintParseQuat(prhs[4],quat_des);
        double conethreshold = rigidBodyConstraintParseGazeConethreshold(prhs[5]);
        double threshold = rigidBodyConstraintParseGazeThreshold(prhs[6]);
        cnst = new WorldGazeOrientConstraint(model,body,axis,quat_des,conethreshold,threshold,tspan);
        plhs[0] = createDrakeConstraintMexPointer((void*)cnst, "deleteRigidBodyConstraintmex","WorldGazeOrientConstraint");
      }
      break;
    // WorldGazeTargetConstraint
    case RigidBodyConstraint::WorldGazeTargetConstraintType:
      {
        if(nrhs != 8 && nrhs != 7)
        {  
          mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","Usage ptr = constructPtrRigidBodyConstraintmex(RigidBodyConstraint::WorldGazeTargetConstraintType,robot.mex_model_ptr,body,axis,target,gaze_origin,conethreshold,tspan)");
        }
        RigidBodyManipulator* model = (RigidBodyManipulator*) getDrakeMexPointer(prhs[1]);
        WorldGazeTargetConstraint* cnst = nullptr;
        Vector2d tspan;
        if(nrhs == 7)
        {
          tspan<< -mxGetInf(),mxGetInf();
        }
        else
        {
          rigidBodyConstraintParseTspan(prhs[7],tspan);
        }
        if(!mxIsNumeric(prhs[2]))
        {
          mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","body must be numeric");
        }
        int body = (int) mxGetScalar(prhs[2])-1;
        checkBodyOrFrameID(body, model);
        Vector3d axis;
        rigidBodyConstraintParse3dUnitVector(prhs[3],axis);
        Vector3d target;
        assert(mxIsNumeric(prhs[4]));
        assert(mxGetM(prhs[4]) == 3 &&mxGetN(prhs[4]) == 1);
        memcpy(target.data(),mxGetPr(prhs[4]),sizeof(double)*3);
        Vector4d gaze_origin;
        Vector3d gaze_origin_tmp;
        assert(mxIsNumeric(prhs[5]));
        assert(mxGetM(prhs[5]) == 3 && mxGetN(prhs[5]) == 1);
        memcpy(gaze_origin_tmp.data(),mxGetPr(prhs[5]),sizeof(double)*3);
        gaze_origin.head(3) = gaze_origin_tmp;
        gaze_origin(3) = 1.0;
        double conethreshold = rigidBodyConstraintParseGazeConethreshold(prhs[6]);
        cnst = new WorldGazeTargetConstraint(model,body,axis,target,gaze_origin,conethreshold,tspan);
        plhs[0] = createDrakeConstraintMexPointer((void*)cnst, "deleteRigidBodyConstraintmex","WorldGazeTargetConstraint");
      }
      break;
    // RelativeGazeTargetConstraint
    case RigidBodyConstraint::RelativeGazeTargetConstraintType:
      {
        if(nrhs != 7 && nrhs != 8 && nrhs != 9)
        {  
          mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","Usage ptr = constructPtrRigidBodyConstraintmex(RigidBodyConstraint::RelativeGazeTargetConstraintType, robot.mex_model_ptr,bodyA,bodyB,axis,target,gaze_origin,conethreshold,tspan)");
        }
        RigidBodyManipulator* model = (RigidBodyManipulator*) getDrakeMexPointer(prhs[1]);
        Vector2d tspan;
        if(nrhs < 9)
        {
          tspan<<-mxGetInf(),mxGetInf();
        }
        else
        {
          rigidBodyConstraintParseTspan(prhs[8],tspan);
        }
        if(!mxIsNumeric(prhs[2]) || !mxIsNumeric(prhs[3]) || mxGetNumberOfElements(prhs[2]) != 1 || mxGetNumberOfElements(prhs[3]) != 1)
        {
          mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","bodyA and bodyB should be numeric scalars");
        }
        int bodyA_idx = (int) mxGetScalar(prhs[2])-1;
        int bodyB_idx = (int) mxGetScalar(prhs[3])-1;
        checkBodyOrFrameID(bodyA_idx, model,"bodyA");
        checkBodyOrFrameID(bodyB_idx, model,"bodyB");
        if(!mxIsNumeric(prhs[4]) || mxGetM(prhs[4]) != 3 || mxGetN(prhs[4]) != 1)
        {
          mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","axis should be 3x1 vector");
        }
        Vector3d axis;
        memcpy(axis.data(),mxGetPr(prhs[4]),sizeof(double)*3);
        double axis_norm = axis.norm();
        if(axis_norm<1e-10)
        {
          mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","axis should be a nonzero vector");
        }
        axis = axis/axis_norm;
        if(!mxIsNumeric(prhs[5]) || mxGetM(prhs[5]) != 3 || mxGetN(prhs[5]) != 1)
        {
          mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","target should be 3x1 vector");
        }
        Vector3d target;
        memcpy(target.data(),mxGetPr(prhs[5]),sizeof(double)*3);
        if(!mxIsNumeric(prhs[6]) || mxGetM(prhs[6]) != 3 || mxGetN(prhs[6]) != 1)
        {
          mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","gaze_origin should be 3x1 vector");
        }
        Vector4d gaze_origin;
        memcpy(gaze_origin.data(),mxGetPr(prhs[6]),sizeof(double)*3);
        gaze_origin(3) = 1.0;
        double conethreshold;
        if(nrhs<8)
        {
          conethreshold = 0.0;
        }
        else
        {
          if(!mxIsNumeric(prhs[7]) || mxGetNumberOfElements(prhs[7]) != 1)
          {
            if(mxGetNumberOfElements(prhs[7]) == 0)
            {
              conethreshold = 0.0;
            }
            else
            {
              mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","conethreshold should be a double scalar");
            }
          }
          conethreshold = mxGetScalar(prhs[7]);
          if(conethreshold<0)
          {
            mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","conethreshold should be nonnegative");
          }
        }
        RelativeGazeTargetConstraint* cnst = new RelativeGazeTargetConstraint(model,bodyA_idx, bodyB_idx,axis,target,gaze_origin,conethreshold,tspan);
        plhs[0] = createDrakeConstraintMexPointer((void*)cnst, "deleteRigidBodyConstraintmex","RelativeGazeTargetConstraint");
      }
      break;
    // RelativeGazeDirConstraint
    case RigidBodyConstraint::RelativeGazeDirConstraintType:
      {
        if(nrhs != 6 && nrhs != 7 && nrhs != 8)
        {  
          mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","Usage ptr = constructPtrRigidBodyConstraintmex(RigidBodyConstraint::RelativeGazeDirConstraintType, robot.mex_model_ptr,bodyA,bodyB,axis,dir,conethreshold,tspan)");
        }
        RigidBodyManipulator* model = (RigidBodyManipulator*) getDrakeMexPointer(prhs[1]);
        Vector2d tspan;
        if(nrhs < 8)
        {
          tspan<<-mxGetInf(),mxGetInf();
        }
        else
        {
          rigidBodyConstraintParseTspan(prhs[7],tspan);
        }
        if(!mxIsNumeric(prhs[2]) || !mxIsNumeric(prhs[3]) || mxGetNumberOfElements(prhs[2]) != 1 || mxGetNumberOfElements(prhs[3]) != 1)
        {
          mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","bodyA and bodyB should be numeric scalars");
        }
        int bodyA_idx = (int) mxGetScalar(prhs[2])-1;
        int bodyB_idx = (int) mxGetScalar(prhs[3])-1;
        checkBodyOrFrameID(bodyA_idx, model,"bodyA");
        checkBodyOrFrameID(bodyB_idx, model,"bodyB");
        if(!mxIsNumeric(prhs[4]) || mxGetM(prhs[4]) != 3 || mxGetN(prhs[4]) != 1)
        {
          mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","axis should be 3x1 vector");
        }
        Vector3d axis;
        memcpy(axis.data(),mxGetPr(prhs[4]),sizeof(double)*3);
        double axis_norm = axis.norm();
        if(axis_norm<1e-10)
        {
          mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","axis should be a nonzero vector");
        }
        axis = axis/axis_norm;
        if(!mxIsNumeric(prhs[5]) || mxGetM(prhs[5]) != 3 || mxGetN(prhs[5]) != 1)
        {
          mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","dir should be 3x1 vector");
        }
        Vector3d dir;
        memcpy(dir.data(),mxGetPr(prhs[5]),sizeof(double)*3);
        double conethreshold;
        if(nrhs<7)
        {
          conethreshold = 0.0;
        }
        else
        {
          if(!mxIsNumeric(prhs[6]) || mxGetNumberOfElements(prhs[6]) != 1)
          {
            if(mxGetNumberOfElements(prhs[6]) == 0)
            {
              conethreshold = 0.0;
            }
            else
            {
              mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","conethreshold should be a double scalar");
            }
          }
          conethreshold = mxGetScalar(prhs[6]);
          if(conethreshold<0)
          {
            mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","conethreshold should be nonnegative");
          }
        }
        RelativeGazeDirConstraint* cnst = new RelativeGazeDirConstraint(model,bodyA_idx, bodyB_idx,axis,dir,conethreshold,tspan);
        plhs[0] = createDrakeConstraintMexPointer((void*)cnst, "deleteRigidBodyConstraintmex","RelativeGazeDirConstraint");
      }
      break;
      // WorldCoMConstraint
    case RigidBodyConstraint::WorldCoMConstraintType:
      {
        if(nrhs != 4 && nrhs != 5 && nrhs != 6)
        {
          mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","Usage ptr = constructPtrRigidBodyConstraintmex(RigidBodyConstraint::WorldCoMConstraintType,robot.mex_model_ptr,lb,ub,tspan,robotnum)");
        }
        RigidBodyManipulator* model = (RigidBodyManipulator*) getDrakeMexPointer(prhs[1]);
        WorldCoMConstraint* cnst = nullptr;
        Vector2d tspan;
        int* robotnum;
        int num_robot;
        if(nrhs <= 5)
        {
          num_robot = 1;
          robotnum = new int[num_robot];
          robotnum[0] = 0;
        }
        else
        {
          num_robot = mxGetNumberOfElements(prhs[5]);
          double* robotnum_tmp = new double[num_robot];
          robotnum = new int[num_robot];
          memcpy(robotnum_tmp,mxGetPr(prhs[5]),sizeof(double)*num_robot);
          for(int i = 0;i<num_robot;i++)
          {
            robotnum[i] = (int) robotnum_tmp[i]-1;
          }
          delete[] robotnum_tmp;
        }
        if(nrhs<=4)
        {
          tspan<<-mxGetInf(),mxGetInf();
        }
        else
        {
          rigidBodyConstraintParseTspan(prhs[4],tspan);
        }
        set<int> robotnumset(robotnum,robotnum+num_robot);
        int n_pts = 1;
        if(mxGetM(prhs[2]) != 3 || mxGetM(prhs[3]) != 3 || mxGetN(prhs[2]) != n_pts || mxGetN(prhs[3]) != n_pts || !mxIsNumeric(prhs[2]) || !mxIsNumeric(prhs[3]))
        {
          mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","lb and ub should both be 3x1 double vectors");
        }
        Vector3d lb;
        Vector3d ub;
        memcpy(lb.data(),mxGetPr(prhs[2]),sizeof(double)*3);
        memcpy(ub.data(),mxGetPr(prhs[3]),sizeof(double)*3);
        cnst = new WorldCoMConstraint(model,lb,ub,tspan,robotnumset);
        plhs[0] = createDrakeConstraintMexPointer((void*)cnst,"deleteRigidBodyConstraintmex","WorldCoMConstraint");
        delete[] robotnum;
      }
      break;
      // WorldPositionConstraint
    case RigidBodyConstraint::WorldPositionConstraintType:
      {
        if(nrhs!= 7 && nrhs != 6)
        {
          mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","Usage ptr = constructPtrRigidBodyConstraintmex(RigidBodyConstraint::WorldPositionConstraintType, robot.mex_model_ptr,body,pts,lb,ub,tspan)");
        }
        RigidBodyManipulator* model = (RigidBodyManipulator*) getDrakeMexPointer(prhs[1]);
        WorldPositionConstraint* cnst = nullptr;
        Vector2d tspan;
        if(nrhs <= 6)
        {
          tspan<< -mxGetInf(), mxGetInf();
        }
        else
        {
          rigidBodyConstraintParseTspan(prhs[6],tspan);
        }
        if(!mxIsNumeric(prhs[2]) || mxGetM(prhs[2])!= 1 || mxGetN(prhs[2]) != 1)
        {
          mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","body must be numeric");
        }
        int body = (int) mxGetScalar(prhs[2])-1;
        checkBodyOrFrameID(body, model);
        int n_pts = mxGetN(prhs[3]);
        if(!mxIsNumeric(prhs[3])||mxGetM(prhs[3]) != 3)
        {
          mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","Argument 3 should be a double matrix with 3 rows");
        }
        MatrixXd pts_tmp(3,n_pts);
        memcpy(pts_tmp.data(),mxGetPr(prhs[3]),sizeof(double)*3*n_pts);
        MatrixXd pts(4,n_pts);
        pts.block(0,0,3,n_pts) = pts_tmp;
        pts.block(3,0,1,n_pts) = MatrixXd::Ones(1,n_pts);

        MatrixXd lb(3,n_pts);
        MatrixXd ub(3,n_pts);
        if(mxGetM(prhs[4]) != 3 || mxGetN(prhs[4]) != n_pts || mxGetM(prhs[5]) != 3 || mxGetN(prhs[5]) != n_pts)
        {
          mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","lb and ub should both be 3xn_pts double matrix");
        }
        memcpy(lb.data(),mxGetPr(prhs[4]),sizeof(double)*3*n_pts);
        memcpy(ub.data(),mxGetPr(prhs[5]),sizeof(double)*3*n_pts);
        cnst = new WorldPositionConstraint(model,body,pts,lb,ub,tspan);
        plhs[0] = createDrakeConstraintMexPointer((void*)cnst,"deleteRigidBodyConstraintmex","WorldPositionConstraint");
      }
      break;
    // WorldPositionInFrameConstraint
    case RigidBodyConstraint::WorldPositionInFrameConstraintType:
      {
        if(nrhs!= 8 && nrhs != 7)
        {
          mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","Usage ptr = constructPtrRigidBodyConstraintmex(RigidBodyConstraint::WorldPositionInFrameConstraint, robot.mex_model_ptr,body,pts,lb,ub,tspan)");
        }
        RigidBodyManipulator* model = (RigidBodyManipulator*) getDrakeMexPointer(prhs[1]);
        WorldPositionInFrameConstraint* cnst = nullptr;
        Vector2d tspan;
        if(nrhs <= 7)
        {
          tspan<< -mxGetInf(), mxGetInf();
        }
        else
        {
          rigidBodyConstraintParseTspan(prhs[7],tspan);
        }
        int body = (int) mxGetScalar(prhs[2])-1;
        checkBodyOrFrameID(body, model);
        int n_pts = mxGetN(prhs[3]);
        if(!mxIsNumeric(prhs[3])||mxGetM(prhs[3]) != 3)
        {
          mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","Argument 3 should be a double matrix with 3 rows");
        }
        MatrixXd pts_tmp(3,n_pts);
        memcpy(pts_tmp.data(),mxGetPr(prhs[3]),sizeof(double)*3*n_pts);
        MatrixXd pts(4,n_pts);
        pts.block(0,0,3,n_pts) = pts_tmp;
        pts.block(3,0,1,n_pts) = MatrixXd::Ones(1,n_pts);

        if(!mxIsNumeric(prhs[4]) || mxGetM(prhs[4]) != 4 || mxGetN(prhs[4]) != 4)
        {
          mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","Argument 4 should be a 4x4 double matrix");
        }
        Matrix4d T_world_to_frame;
        memcpy(T_world_to_frame.data(),mxGetPr(prhs[4]),sizeof(double)*16);

        MatrixXd lb(3,n_pts);
        MatrixXd ub(3,n_pts);
        if(mxGetM(prhs[5]) != 3 || mxGetN(prhs[5]) != n_pts || mxGetM(prhs[6]) != 3 || mxGetN(prhs[6]) != n_pts)
        {
          mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","lb and ub should both be 3xn_pts double matrix");
        }
        memcpy(lb.data(),mxGetPr(prhs[5]),sizeof(double)*3*n_pts);
        memcpy(ub.data(),mxGetPr(prhs[6]),sizeof(double)*3*n_pts);

        cnst = new WorldPositionInFrameConstraint(model,body,pts,T_world_to_frame,
                                                  lb,ub,tspan);
        plhs[0] = createDrakeConstraintMexPointer((void*)cnst,"deleteRigidBodyConstraintmex","WorldPositionInFrameConstraint");
      }
      break;
      // WorldQuatConstraint
    case RigidBodyConstraint::WorldQuatConstraintType:
      {
        if(nrhs!= 6 && nrhs!= 5)
        {
          mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","Usage ptr = constructPtrRigidBodyConstraintmex(RigidBodyConstraint::WorldQuatConstraintType,robot.mex_model_ptr,body,quat_des,tol,tspan)");
        }
        RigidBodyManipulator* model = (RigidBodyManipulator*) getDrakeMexPointer(prhs[1]);
        WorldQuatConstraint* cnst = nullptr;
        Vector2d tspan;
        if(nrhs <= 5)
        {
          tspan<<-mxGetInf(),mxGetInf();
        }
        else
        {
          rigidBodyConstraintParseTspan(prhs[5],tspan);
        }
        int body = (int) mxGetScalar(prhs[2])-1;
        checkBodyOrFrameID(body, model);
        Vector4d quat_des;
        rigidBodyConstraintParseQuat(prhs[3],quat_des);
        double tol = mxGetScalar(prhs[4]);
        cnst = new WorldQuatConstraint(model,body,quat_des,tol,tspan);
        plhs[0] = createDrakeConstraintMexPointer((void*)cnst,"deleteRigidBodyConstraintmex","WorldQuatConstraint");
      }
      break;
      // Point2PointDistanceConstraint
    case RigidBodyConstraint::Point2PointDistanceConstraintType:
      {
        if(nrhs != 8 && nrhs != 9)
        {
          mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","Usage ptr = constructRigidBodyConstraintmex(RigidBodyConstraint::Point2PointDistanceConstraintType, robot.mex_model_ptr,bodyA,bodyB,ptA,ptB,dist_lb,dist_ub,tspan");
        }
        RigidBodyManipulator *model = (RigidBodyManipulator*) getDrakeMexPointer(prhs[1]);
        Vector2d tspan;
        if(nrhs <= 8)
        {
          tspan<< -mxGetInf(), mxGetInf();
        }
        else
        {
          rigidBodyConstraintParseTspan(prhs[8],tspan);
        }
        if(!mxIsNumeric(prhs[2]) || !mxIsNumeric(prhs[3]))
        {
          mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","bodyA and bodyB must be numeric");
        }
        if(mxGetNumberOfElements(prhs[2]) != 1 || mxGetNumberOfElements(prhs[3]) != 1)
        {
          mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","bodyA and bodyB must be a scalar");
        }
        int bodyA = (int) mxGetScalar(prhs[2])-1;
        int bodyB = (int) mxGetScalar(prhs[3])-1;
        checkBodyOrFrameID(bodyA, model,"bodyA");
        checkBodyOrFrameID(bodyB, model,"bodyB");
        if(bodyA == bodyB)
        {
          mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","bodyA and bodyB should be different");
        }
        if(!mxIsNumeric(prhs[4]) || !mxIsNumeric(prhs[5]))
        {
          mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","ptA and ptB should be numeric");
        }
        int npts = mxGetN(prhs[4]);
        if(mxGetM(prhs[4]) != 3 || mxGetM(prhs[5]) != 3)
        {
          mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","ptA and ptB should have 3 rows");
        }
        if(mxGetN(prhs[5]) != npts)
        {
          mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","ptA and ptB should have the same number of columns");
        }
        MatrixXd ptA_tmp(3,npts);
        MatrixXd ptB_tmp(3,npts);
        memcpy(ptA_tmp.data(),mxGetPr(prhs[4]),sizeof(double)*3*npts);
        memcpy(ptB_tmp.data(),mxGetPr(prhs[5]),sizeof(double)*3*npts);
        MatrixXd ptA(4,npts);
        MatrixXd ptB(4,npts);
        ptA.block(0,0,3,npts) = ptA_tmp;
        ptB.block(0,0,3,npts) = ptB_tmp;
        ptA.row(3) = MatrixXd::Ones(1,npts);
        ptB.row(3) = MatrixXd::Ones(1,npts);
        if(!mxIsNumeric(prhs[6]) || !mxIsNumeric(prhs[7]) || mxGetM(prhs[6]) != 1 || mxGetM(prhs[7]) != 1 || mxGetN(prhs[6]) != npts || mxGetN(prhs[7]) != npts)
        {
          mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","dist_lb and dist_ub must be 1 x npts numeric");
        }
        VectorXd dist_lb(npts);
        VectorXd dist_ub(npts);
        memcpy(dist_lb.data(),mxGetPr(prhs[6]),sizeof(double)*npts);
        memcpy(dist_ub.data(),mxGetPr(prhs[7]),sizeof(double)*npts);
        for(int i = 0;i<npts;i++)
        {
          if(dist_lb(i)>dist_ub(i))
          {
            mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","dist_lb must be no larger than dist_ub");
          }
        }
        Point2PointDistanceConstraint* cnst = new Point2PointDistanceConstraint(model,bodyA,bodyB,ptA,ptB,dist_lb,dist_ub,tspan);
        plhs[0] = createDrakeConstraintMexPointer((void*)cnst,"deleteRigidBodyConstraintmex","Point2PointDistanceConstraint");
      }
      break;
    // Point2LineSegDistConstraint
    case RigidBodyConstraint::Point2LineSegDistConstraintType:
      {
        if(nrhs != 8 && nrhs != 9)
        {
          mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","Usage ptr = constructPtrRigidBodyConstraintmex(RigidBodyConstraint::Point2LineSegDistConstraint, robot.mex_model_ptr,pt_body,pt,line_body,line_ends,lb,ub,tspan");
        }
        RigidBodyManipulator *model = (RigidBodyManipulator*) getDrakeMexPointer(prhs[1]);
        Vector2d tspan;
        if(nrhs <= 8)
        {
          tspan<< -mxGetInf(), mxGetInf();
        }
        else
        {
          rigidBodyConstraintParseTspan(prhs[8],tspan);
        }
        if(!mxIsNumeric(prhs[2])||mxGetNumberOfElements(prhs[2]) != 1)
        {
          mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","pt_body should be a numeric scalar");
        }
        int pt_body = (int) mxGetScalar(prhs[2])-1;
        if(pt_body>=model->num_bodies || pt_body<0)
        {
          mexErrMsgIdAndTxt("Drake:constructPtrPoint2LineSegDistConstraintmex:BadInputs","pt_body is invalid");
        }
        if(!mxIsNumeric(prhs[3]) || mxGetM(prhs[3]) != 3 || mxGetN(prhs[3]) != 1)
        {
          mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","pt should be a 3x1 vector");
        }
        Vector4d pt;
        memcpy(pt.data(),mxGetPr(prhs[3]),sizeof(double)*3);
        pt(3) = 1.0;
        if(!mxIsNumeric(prhs[4])||mxGetNumberOfElements(prhs[4]) != 1)
        {
          mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","line_body should be a numeric scalar");
        }
        int line_body = (int) mxGetScalar(prhs[4])-1;
        if(line_body>=model->num_bodies || line_body<0)
        {
          mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","line_body is invalid");
        }
        if(!mxIsNumeric(prhs[5]) || mxGetM(prhs[5]) != 3 || mxGetN(prhs[5]) != 2)
        {
          mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","line_ends should be a 3x2 vector");
        }
        Matrix<double,4,2> line_ends;
        Matrix<double,3,2> line_ends_tmp;
        memcpy(line_ends_tmp.data(),mxGetPr(prhs[5]),sizeof(double)*6);
        line_ends.block(0,0,3,2) = line_ends_tmp;
        line_ends.row(3) = MatrixXd::Ones(1,2);
        if(!mxIsNumeric(prhs[6]) || !mxIsNumeric(prhs[7]) || mxGetNumberOfElements(prhs[6]) != 1 || mxGetNumberOfElements(prhs[7]) != 1)
        {
          mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","dist_lb, dist_ub should be scalars");
        }
        double dist_lb = mxGetScalar(prhs[6]);
        double dist_ub = mxGetScalar(prhs[7]);
        if(dist_lb<0 || dist_lb>dist_ub)
        {
          mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","dist_lb should be nonnegative, and dist_ub should be no less than dist_lb");
        }
        Point2LineSegDistConstraint* cnst = new Point2LineSegDistConstraint(model,pt_body,pt,line_body,line_ends,dist_lb,dist_ub,tspan);
        plhs[0] = createDrakeConstraintMexPointer((void*) cnst,"deleteRigidBodyConstraintmex","Point2LineSegDistConstraint");
      }
      break;
    // WorldFixedPositionConstraint
    case RigidBodyConstraint::WorldFixedPositionConstraintType:
      {
        if(nrhs != 5 && nrhs != 4)
        {
          mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs", "Usage ptr = constructPtrRigidBodyConstraintmex(RigidBodyConstraint::WorldFixedPositionConstraintType, robot.mex_model_ptr,body,pts,tspan)");
        }
        RigidBodyManipulator *model = (RigidBodyManipulator*) getDrakeMexPointer(prhs[1]);
        WorldFixedPositionConstraint* cnst = nullptr;
        Vector2d tspan;
        if(nrhs <= 4)
        {
          tspan<< -mxGetInf(),mxGetInf();
        }
        else
        {
          rigidBodyConstraintParseTspan(prhs[4],tspan);
        }
        int body = (int) mxGetScalar(prhs[2])-1;
        int n_pts = mxGetN(prhs[3]);
        if(!mxIsNumeric(prhs[3])||mxGetM(prhs[3]) != 3)
        {
          mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","Argument 4 should be a double matrix with 3 rows");
        }
        MatrixXd pts_tmp(3,n_pts);
        memcpy(pts_tmp.data(),mxGetPr(prhs[3]),sizeof(double)*3*n_pts);
        MatrixXd pts(4,n_pts);
        pts.block(0,0,3,n_pts) = pts_tmp;
        pts.block(3,0,1,n_pts) = MatrixXd::Ones(1,n_pts);

        cnst = new WorldFixedPositionConstraint(model,body,pts,tspan);
        plhs[0] = createDrakeConstraintMexPointer((void*)cnst,"deleteRigidBodyConstraintmex","WorldFixedPositionConstraint");
      }
      break;
    // WorldFixedOrientConstraint
    case RigidBodyConstraint::WorldFixedOrientConstraintType:
      {
        if(nrhs != 4 && nrhs != 3)
        {
          mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs", "Usage ptr = constructPtrRigidBodyConstraintmex(RigidBodyConstraint::WorldFixedOrientConstraintType,robot.mex_model_ptr,body,tspan)");
        }
        RigidBodyManipulator *model = (RigidBodyManipulator*) getDrakeMexPointer(prhs[1]);
        WorldFixedOrientConstraint* cnst = nullptr;
        Vector2d tspan;
        if(nrhs <= 3)
        {
          tspan<< -mxGetInf(),mxGetInf();
        }
        else
        {
          rigidBodyConstraintParseTspan(prhs[3],tspan);
        }
        int body = (int) mxGetScalar(prhs[2])-1;

        cnst = new WorldFixedOrientConstraint(model,body,tspan);
        plhs[0] = createDrakeConstraintMexPointer((void*)cnst,"deleteRigidBodyConstraintmex","WorldFixedOrientConstraint");
      }
      break;
    // WorldFixedBodyPoseConstraint
    case RigidBodyConstraint::WorldFixedBodyPoseConstraintType:
      {
        if(nrhs != 4 && nrhs != 3)
        {
          mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs", "Usage ptr = constructPtrRigidBodyConstraintmex(RigidBodyConstraint::WorldFixedBodyPoseConstraintType,robot.mex_model_ptr,body,tspan)");
        }
        RigidBodyManipulator *model = (RigidBodyManipulator*) getDrakeMexPointer(prhs[1]);
        WorldFixedBodyPoseConstraint* cnst = nullptr;
        Vector2d tspan;
        if(nrhs <= 3)
        {
          tspan<< -mxGetInf(),mxGetInf();
        }
        else
        {
          rigidBodyConstraintParseTspan(prhs[3],tspan);
        }
        int body = (int) mxGetScalar(prhs[2])-1;

        cnst = new WorldFixedBodyPoseConstraint(model,body,tspan);
        plhs[0] = createDrakeConstraintMexPointer((void*)cnst,"deleteRigidBodyConstraintmex","WorldFixedBodyPoseConstraint");
      }
      break;
      // PostureChangeConstraintType
    case RigidBodyConstraint::PostureChangeConstraintType:
      {
        if(nrhs != 6 && nrhs != 5)
        {
          mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","Usage ptr = constructPtrRigidBodyConstraintmex(RigidBodyConstraint::PostureChangeConstraintType,robot.mex_model_ptr,joint_ind,lb_change,ub_change,tspan");
        }
        RigidBodyManipulator* model = (RigidBodyManipulator*) getDrakeMexPointer(prhs[1]);
        Vector2d tspan;
        if(nrhs <= 5)
        {
          tspan<<-mxGetInf(),mxGetInf();
        }
        else
        {
          rigidBodyConstraintParseTspan(prhs[5],tspan);
        }
        if(!mxIsNumeric(prhs[2]) || mxGetN(prhs[2]) != 1)
        {
          mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","joint_ind must be a column numeric vector");
        }
        int num_joints = mxGetM(prhs[2]);
        VectorXd joint_ind_tmp(num_joints);
        memcpy(joint_ind_tmp.data(),mxGetPr(prhs[2]),sizeof(double)*num_joints);
        VectorXi joint_ind(num_joints);
        for(int i = 0;i<num_joints;i++)
        {
          joint_ind(i) = (int) joint_ind_tmp(i)-1;
          if(joint_ind(i)<0 || joint_ind(i)>=model->num_dof)
          {
            mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","joint_ind must be within [1,nq]");
          }
        }
        if(!mxIsNumeric(prhs[3]) || mxGetM(prhs[3]) != num_joints || mxGetN(prhs[3]) != 1 ||!mxIsNumeric(prhs[4]) || mxGetM(prhs[4]) != num_joints || mxGetN(prhs[4]) != 1)
        {
          mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","lb_change and upper bound change must be both numeric vector, with the same size as joint_ind");
        }
        VectorXd lb_change(num_joints);
        VectorXd ub_change(num_joints);
        memcpy(lb_change.data(),mxGetPr(prhs[3]),sizeof(double)*num_joints);
        memcpy(ub_change.data(),mxGetPr(prhs[4]),sizeof(double)*num_joints);
        for(int i = 0;i<num_joints;i++)
        {
          double lb_change_min = model->joint_limit_min[joint_ind(i)]-model->joint_limit_max[joint_ind(i)];
          double ub_change_max = model->joint_limit_max[joint_ind(i)]-model->joint_limit_min[joint_ind(i)];
          lb_change(i) = (lb_change_min<lb_change(i)?lb_change(i):lb_change_min);
          ub_change(i) = (ub_change_max>ub_change(i)?ub_change(i):ub_change_max);
          if(lb_change(i)>ub_change(i))
          {
            mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","lb_change must be no larger than ub_change");
          }
        }
        PostureChangeConstraint* cnst = new PostureChangeConstraint(model,joint_ind,lb_change,ub_change,tspan);
        plhs[0] = createDrakeConstraintMexPointer((void*)cnst,"deleteRigidBodyConstraintmex","PostureChangeConstraint");
      }
      break;
    case RigidBodyConstraint::RelativePositionConstraintType:
      {
        if(nrhs != 9 && nrhs != 8)
        {
          mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","Usage ptr = constructPtrRigidBodyConstraintmex(RigidBodyConstraint::RelativePositionConstraintType,robot.mex_model_ptr,pts,lb,ub,bodyA_idx,bodyB_idx,bTbp,tspan");
        }
        RigidBodyManipulator* model = (RigidBodyManipulator*) getDrakeMexPointer(prhs[1]);
        Vector2d tspan;
        if(nrhs <= 8)
        {
          tspan<<-mxGetInf(),mxGetInf();
        }
        else
        {
          rigidBodyConstraintParseTspan(prhs[8],tspan);
        }
        if(!mxIsNumeric(prhs[2])|| mxGetM(prhs[2]) != 3)
        {
          mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","Argument 3 (pts) should be a double matrix with 3 rows");
        }
        int n_pts = mxGetN(prhs[3]);
        MatrixXd pts_tmp(3,n_pts);
        memcpy(pts_tmp.data(),mxGetPr(prhs[2]),sizeof(double)*3*n_pts);
        MatrixXd pts(4,n_pts);
        pts.block(0,0,3,n_pts) = pts_tmp;
        pts.block(3,0,1,n_pts) = MatrixXd::Ones(1,n_pts);

        MatrixXd lb(3,n_pts);
        MatrixXd ub(3,n_pts);
        if(!mxIsNumeric(prhs[3]) || mxGetM(prhs[3]) != 3 || mxGetN(prhs[3]) != n_pts || !mxIsNumeric(prhs[4]) || mxGetM(prhs[4]) != 3 || mxGetN(prhs[4]) != n_pts)
        {
          mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","lb and ub should both be 3xn_pts double matrix");
        }
        memcpy(lb.data(),mxGetPr(prhs[3]),sizeof(double)*3*n_pts);
        memcpy(ub.data(),mxGetPr(prhs[4]),sizeof(double)*3*n_pts);
        
        if(!mxIsNumeric(prhs[5]) || mxGetM(prhs[5]) != 1 || mxGetN(prhs[5]) != 1 || !mxIsNumeric(prhs[6]) || mxGetM(prhs[6]) != 1 || mxGetN(prhs[6]) != 1)
        {
          mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","bodyA_idx and bodyB_idx should be numeric scalars");
        }
        int bodyA_idx = static_cast<int>(mxGetScalar(prhs[5])-1);
        int bodyB_idx = static_cast<int>(mxGetScalar(prhs[6])-1);
        checkBodyOrFrameID(bodyA_idx,model,"bodyA");
        checkBodyOrFrameID(bodyB_idx,model,"bodyB");

        Matrix<double,7,1> bTbp;
        if(!mxIsNumeric(prhs[7]) || mxGetM(prhs[7]) != 7 || mxGetN(prhs[7]) != 1)
        {
          mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","bTbp should be 7x1 numeric vector");
        }
        memcpy(bTbp.data(),mxGetPr(prhs[7]),sizeof(double)*7);
        double quat_norm = bTbp.block(3,0,4,1).norm();
        if(abs(quat_norm-1)>1e-5)
        {
          mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","bTbp(4:7) should be a unit quaternion");
        }
        bTbp.block(3,0,4,1) /= quat_norm;
        RelativePositionConstraint* cnst = new RelativePositionConstraint(model,pts,lb,ub,bodyA_idx,bodyB_idx,bTbp,tspan);
        plhs[0] = createDrakeConstraintMexPointer((void*)cnst,"deleteRigidBodyConstraintmex","RelativePositionConstraint");
      }
      break;
    case RigidBodyConstraint::RelativeQuatConstraintType:
      {
        if(nrhs != 7 && nrhs != 6)
        {
          mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","Usage ptr = constructPtrRigidBodyConstraintmex(RigidBodyConstraint::RelativeQuatConstraintType,robot.mex_model_ptr,bodyA_idx,bodyB_idx,quat_des,tol,tspan");
        }
        RigidBodyManipulator* model = (RigidBodyManipulator*) getDrakeMexPointer(prhs[1]);
        Vector2d tspan;
        if(nrhs <= 6)
        {
          tspan<<-mxGetInf(),mxGetInf();
        }
        else
        {
          rigidBodyConstraintParseTspan(prhs[6],tspan);
        }
        if(!mxIsNumeric(prhs[2])|| mxGetM(prhs[2]) != 1 || mxGetN(prhs[2]) != 1 || !mxIsNumeric(prhs[3])|| mxGetM(prhs[3]) != 1 || mxGetN(prhs[3]) != 1)
        {
          mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","Argument 3 (bodyA_idx) and 4 (bodyB_idx) should be both scalars");
        }
        int bodyA_idx = static_cast<int>(mxGetScalar(prhs[2]))-1;
        int bodyB_idx = static_cast<int>(mxGetScalar(prhs[3]))-1;
        checkBodyOrFrameID(bodyA_idx,model,"bodyA");
        checkBodyOrFrameID(bodyB_idx,model,"bodyB");
        if(!mxIsNumeric(prhs[4]) || mxGetM(prhs[4]) != 4 || mxGetN(prhs[4]) != 1)
        {
          mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","Argument 5 (quat_des) should be 4 x 1 double vector");
        }
        Vector4d quat_des;
        memcpy(quat_des.data(),mxGetPr(prhs[4]),sizeof(double)*4);
        double quat_norm = quat_des.norm();
        if(abs(quat_norm-1.0)>1e-5)
        {
          mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","Argument 5 should be a quaternion with unit length");
        }
        if(!mxIsNumeric(prhs[5]) || mxGetM(prhs[5]) != 1 || mxGetN(prhs[5]) != 1)
        {
          mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","Argument 6 (tol) should be a double scalar");
        }
        double tol = mxGetScalar(prhs[5]);
        RelativeQuatConstraint* cnst = new RelativeQuatConstraint(model,bodyA_idx,bodyB_idx,quat_des,tol,tspan);
        plhs[0] = createDrakeConstraintMexPointer((void*)cnst,"deleteRigidBodyConstraintmex","RelativeQuatConstraint");
      }
      break;
    case RigidBodyConstraint::MinDistanceConstraintType:
      {
        if(nrhs != 4 && nrhs != 5)
        {
          mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs",
              "Usage ptr = constructPtrRigidBodyConstraintmex(RigidBodyConstraint::MinDistanceConstraintType, robot.mex_model_ptr,min_distance,active_collision_options,tspan)");
        }
        RigidBodyManipulator* model = (RigidBodyManipulator*) getDrakeMexPointer(prhs[1]);
        Vector2d tspan;
        if(nrhs == 4)
        {
          tspan<< -mxGetInf(), mxGetInf();
        }
        else
        {
          rigidBodyConstraintParseTspan(prhs[4],tspan);
        }

        double min_distance = (double) mxGetScalar(prhs[2]);

        // Parse `active_collision_options`
        vector<int> active_bodies_idx;
        set<string> active_group_names;
        // First get the list of body indices for which to compute distances
        const mxArray* active_collision_options = prhs[3];
        const mxArray* body_idx = mxGetField(active_collision_options,0,"body_idx");
        if (body_idx != NULL) {
          //DEBUG
          //cout << "collisionDetectmex: Received body_idx" << endl;
          //END_DEBUG
          int n_active_bodies = mxGetNumberOfElements(body_idx);
          //DEBUG
          //cout << "collisionDetectmex: n_active_bodies = " << n_active_bodies << endl;
          //END_DEBUG
          active_bodies_idx.resize(n_active_bodies);
          memcpy(active_bodies_idx.data(),(int*) mxGetData(body_idx),
              sizeof(int)*n_active_bodies);
          transform(active_bodies_idx.begin(),active_bodies_idx.end(),
              active_bodies_idx.begin(),
              [](int i){return --i;});
        }

        // Then get the group names for which to compute distances
        const mxArray* collision_groups = mxGetField(active_collision_options,0,
            "collision_groups");
        if (collision_groups != NULL) {
          for (const string& str : get_strings(collision_groups)) {
            active_group_names.insert(str);
          }
        }

        auto cnst = new MinDistanceConstraint(model,min_distance,active_bodies_idx,active_group_names,tspan);
        plhs[0] = createDrakeConstraintMexPointer((void*)cnst,"deleteRigidBodyConstraintmex",
                                        "MinDistanceConstraint");
      }
      break;
    default:
      mexErrMsgIdAndTxt("Drake:constructPtrRigidBodyConstraintmex:BadInputs","Unsupported constraint type");
      break;

  }
}