Beispiel #1
0
SensorsMeasurements::SensorsMeasurements(const SensorsList &sensorsList)
{
    this->pimpl = new SensorsMeasurementsPrivateAttributes;
    this->pimpl->SixAxisFTSensorsMeasurements.resize(sensorsList.getNrOfSensors(iDynTree::SIX_AXIS_FORCE_TORQUE));
    this->pimpl->AccelerometerMeasurements.resize(sensorsList.getNrOfSensors(iDynTree::ACCELEROMETER));
    this->pimpl->GyroscopeMeasurements.resize(sensorsList.getNrOfSensors(iDynTree::GYROSCOPE));
}
Beispiel #2
0
bool SensorsMeasurements::resize(const SensorsList &sensorsList)
{
    Wrench zeroWrench;zeroWrench.zero();
    LinAcceleration zeroLinAcc;zeroLinAcc.zero();
    AngVelocity zeroAngVel;zeroAngVel.zero();

    this->pimpl->SixAxisFTSensorsMeasurements.resize(sensorsList.getNrOfSensors(iDynTree::SIX_AXIS_FORCE_TORQUE),zeroWrench);
    this->pimpl->AccelerometerMeasurements.resize(sensorsList.getNrOfSensors(iDynTree::ACCELEROMETER),zeroLinAcc);
    this->pimpl->GyroscopeMeasurements.resize(sensorsList.getNrOfSensors(iDynTree::GYROSCOPE),zeroAngVel);

    return true;
}
Beispiel #3
0
void SensorsList::constructor(const SensorsList& other)
{
    this->pimpl = new SensorsListPimpl();
    this->pimpl->VecSensors.resize(NR_OF_SENSOR_TYPES,std::vector<Sensor *>(0));
    this->pimpl->NamesSensors.resize(NR_OF_SENSOR_TYPES);
    for(int sens_type = 0; sens_type < NR_OF_SENSOR_TYPES; sens_type++ )
    {
        for(unsigned int sens = 0; sens < other.getNrOfSensors((SensorType)sens_type); sens++ )
        {
            this->pimpl->VecSensors[sens_type].push_back(other.pimpl->VecSensors[sens_type][sens]->clone());
            std::string sensor_name = other.getSensor((SensorType)sens_type,sens)->getName();
            this->pimpl->NamesSensors[sens_type].insert(std::pair<std::string,int>(sensor_name,sens));
        }
    }
}
Beispiel #4
0
void        Generic1DOFJointSensorGroup::SetSensorsList(const SensorsList& list){
    mSensorList.clear();
    mSensorCount = 0;
    for(unsigned int i=0;i<list.size();i++){
        Generic1DOFJointSensor *sensor = Generic1DOFJointSensor::Cast(list[i]);
        if(sensor){
            mSensorList.push_back(sensor);
            mSensorCount ++;
        }
    }
    mPosition.Resize(mSensorCount,false);
    mVelocity.Resize(mSensorCount,false);
    mAcceleration.Resize(mSensorCount,false);
    mTorque.Resize(mSensorCount,false);
    mLimits[0].Resize(mSensorCount,false);
    mLimits[1].Resize(mSensorCount,false);

    mPosition.Zero();
    mVelocity.Zero();
    mAcceleration.Zero();
    mTorque.Zero();
    mLimits[0].Zero();
    mLimits[1].Zero();
}
Beispiel #5
0
int     Sensor::SensorsListSetFromStream(SensorsList & list,const void* memory){
    char* mem = (char*) memory;
    for(size_t i=0;i<list.size();i++)
        mem += list[i]->SetFromStream(mem);
    return ((char*)mem)-((char*)memory);
}
Beispiel #6
0
int     Sensor::SensorsListStreamSize(SensorsList & list){
    int result=0;
    for(size_t i=0;i<list.size();i++)
        result += list[i]->StreamSize();
    return result;
}
Beispiel #7
0
bool sensorsFromURDFString(const std::string& urdfXml,
                           const Model & model,
                           SensorsList & outputSensors)
{
    SensorsList newSensors;

    bool parsingSuccessful = true;

    /* parse custon  urdf */
    TiXmlDocument tiUrdfXml;
    tiUrdfXml.Parse(urdfXml.c_str());

    TiXmlElement* robotXml = tiUrdfXml.FirstChildElement("robot");

    // Several sensor types have been proposed for use in URDF,
    // see http://wiki.ros.org/urdf/XML/sensor/proposals ,
    // but few of them (the one more relevant to dynamics) are supported by iDynTree
    // To avoid printing too many warnings, a warning about the ignored sensor
    // is printed only if the sensor has a type that is not on the following list
    // In this way we can print a warning to catch eventual typos, but avoid flooding
    // the user with meaningless warnings if he loads (for example) a model full of cameras
    std::vector<std::string> sensorTypesUsedInURDFButNotSupportedInIDynTree;
    sensorTypesUsedInURDFButNotSupportedInIDynTree.push_back("camera");
    sensorTypesUsedInURDFButNotSupportedInIDynTree.push_back("ray");
    sensorTypesUsedInURDFButNotSupportedInIDynTree.push_back("imu");
    sensorTypesUsedInURDFButNotSupportedInIDynTree.push_back("magnetometer");
    sensorTypesUsedInURDFButNotSupportedInIDynTree.push_back("gps");
    sensorTypesUsedInURDFButNotSupportedInIDynTree.push_back("contact");
    sensorTypesUsedInURDFButNotSupportedInIDynTree.push_back("sonar");
    sensorTypesUsedInURDFButNotSupportedInIDynTree.push_back("rfidtag");
    sensorTypesUsedInURDFButNotSupportedInIDynTree.push_back("rfid");


    // Get all the sensors elements of robot element
    for (TiXmlElement* sensorXml = robotXml->FirstChildElement("sensor");
         sensorXml; sensorXml = sensorXml->NextSiblingElement("sensor"))
    {
        if( sensorXml->Attribute("name")==NULL ||
            sensorXml->Attribute("type")==NULL )
        {
            std::cerr << "[ERROR] Sensor name or type specified incorrectly." << std::endl;
            parsingSuccessful = false;
            return false;
        }

        // Parse sensors name
        std::string  sensorName(sensorXml->Attribute("name"));

        // Parse sensor type
        std::string sensorType(sensorXml->Attribute("type"));

        iDynTree::SensorType type;



        if(sensorType.compare("accelerometer") == 0)
        {
            type = ACCELEROMETER;
        }
        else if(sensorType.compare("gyroscope") == 0)
        {
            type = GYROSCOPE;
        }
        else if(sensorType.compare("force_torque") == 0)
        {
            type = SIX_AXIS_FORCE_TORQUE;
        }
        else
        {
            // Print the warning about ignored sensors only if the sensor type is not on the list (to catch typos)
            if( std::find(sensorTypesUsedInURDFButNotSupportedInIDynTree.begin(),sensorTypesUsedInURDFButNotSupportedInIDynTree.end(), sensorType)
                     == sensorTypesUsedInURDFButNotSupportedInIDynTree.end() )
            {
                std::string errString = "Specified sensor type " + sensorType + " of sensor with name " + sensorName +" is not recognised, this sensor was ignored by the iDynTree sensor parser.";
                reportWarning("","sensorsFromURDFString",errString.c_str());
            }
            continue;
        }

        // Parse origin element
        Transform link_H_pose;
        TiXmlElement* originTag = sensorXml->FirstChildElement("origin");
        if( originTag )
        {
            std::string  rpyText(originTag->Attribute("rpy"));
            std::string  xyzText(originTag->Attribute("xyz"));

            std::vector<std::string> rpyElems;
            std::vector<std::string> xyzElems;
            splitString(rpyText,rpyElems);
            splitString(xyzText,xyzElems);

            if( rpyElems.size() != 3 && xyzElems.size() !=3 )
            {
               std::cerr<<"[ERROR] Pose attribute for sensor " << sensorName << " specified incorrectly, parsing failed.";
               parsingSuccessful = false;
               return false;
            }
            double roll  = atof(rpyElems[0].c_str());
            double pitch = atof(rpyElems[1].c_str());
            double yaw   = atof(rpyElems[2].c_str());
            iDynTree::Rotation rot = iDynTree::Rotation::RPY(roll,pitch,yaw);
            double x  = atof(xyzElems[0].c_str());
            double y = atof(xyzElems[1].c_str());
            double z   = atof(xyzElems[2].c_str());
            iDynTree::Position pos(x,y,z);
            link_H_pose = iDynTree::Transform(rot,pos);
        }
        else
        {
            // default value
            link_H_pose = iDynTree::Transform::Identity();
        }

        // Parse parent element
        TiXmlElement* parent = sensorXml->FirstChildElement("parent");

        std::string parentLink, parentJoint;
        JointIndex parentJointIndex = JOINT_INVALID_INDEX;
        LinkIndex  parentLinkIndex  = LINK_INVALID_INDEX;

        if(!parent)
        {
            std::cerr<< "[ERROR] parent element not found in sensor " << sensorName <<
                        ", parsing failed." << std::endl;
            parsingSuccessful = false;
            return false;
        }

        if(parent->Attribute("link")!= NULL)
        {
            parentLink = std::string(parent->Attribute("link"));
            parentLinkIndex = model.getLinkIndex(parentLink);

            if( parentLinkIndex == LINK_INVALID_INDEX )
            {
               std::cerr<< "[ERROR] sensor " << sensorName
                         << " has parent link " << parentLink
                         << " but the link is not found on the model, parsing failed." << std::endl;
                parsingSuccessful = false;
                return false;
            }

            if( type == SIX_AXIS_FORCE_TORQUE )
            {
                std::cerr<< "[ERROR] sensor " << sensorName
                         << " of type force_torque cannot be child of a link "
                         << ", parsing failed." << std::endl;
                parsingSuccessful = false;
                return false;
            }
        }
        else if(parent->Attribute("joint")!=NULL)
        {
            parentJoint = std::string(parent->Attribute("joint"));

            parentJointIndex = model.getJointIndex(parentJoint);

            if( parentJointIndex == JOINT_INVALID_INDEX )
            {
               std::cerr<< "[ERROR] sensor " << sensorName
                         << " has parent joint " << parentJoint
                         << " but the joint is not found on the model, parsing failed." << std::endl;
                parsingSuccessful = false;
                return false;
            }

            if( type == GYROSCOPE )
            {
                std::cerr<< "[ERROR] sensor " << sensorName
                         << " of type gyroscope cannot be child of a joint "
                         << ", parsing failed." << std::endl;
                parsingSuccessful = false;
                return false;
            }

            if( type == ACCELEROMETER )
            {
                std::cerr<< "[ERROR] sensor " << sensorName
                         << " of type accelerometer cannot be child of a joint "
                         << ", parsing failed." << std::endl;
                parsingSuccessful = false;
                return false;
            }
        }
        else
        {
            std::cerr << "[ERROR] Link or Joint attribute for parent element not found in sensor "
                      << sensorName << ", parsing failed." << std::endl;
            parsingSuccessful = false;
            return false;
        }

        // Actually allocate the sensors
        if( type == SIX_AXIS_FORCE_TORQUE )
        {
            // parse frame
            enum { PARENT_LINK_FRAME ,
                   CHILD_LINK_FRAME  ,
                    SENSOR_FRAME } frame_type;

            enum { PARENT_TO_CHILD,
                   CHILD_TO_PARENT } measure_direction_type;

            TiXmlElement* force_torque = sensorXml->FirstChildElement("force_torque");

            if( !force_torque )
            {
                std::cerr<< "[ERROR] sensor " << sensorName
                         << " of type force_torque is missing force_torque element "
                         << ", parsing failed." << std::endl;
                parsingSuccessful = false;
                return false;
            }

            TiXmlElement* frame_el = force_torque->FirstChildElement("frame");
            TiXmlElement* measure_direction_el = force_torque->FirstChildElement("measure_direction");

            // parse frame
            if( !frame_el || !measure_direction_el )
            {
                std::cerr<< "[ERROR] sensor " << sensorName
                         << " of type force_torque is missing frame or measure_direction element "
                         << ", parsing failed." << std::endl;
                parsingSuccessful = false;
                return false;
            }

            std::string frame = frame_el->GetText();
            if( frame == "child" )
            {
                frame_type = CHILD_LINK_FRAME;
            }
            else if( frame == "parent" )
            {
                frame_type = PARENT_LINK_FRAME;
            }
            else if( frame == "sensor" )
            {
                frame_type = SENSOR_FRAME;
            }
            else
            {
                std::cerr<< "[ERROR] sensor " << sensorName
                         << " of type force_torque has unexpected frame content " << frame
                         << ", parsing failed." << std::endl;
                parsingSuccessful = false;
                return false;
            }

            std::string measure_direction = measure_direction_el->GetText();
            if( measure_direction == "parent_to_child" )
            {
                measure_direction_type = PARENT_TO_CHILD;
            }
            else if( measure_direction == "child_to_parent" )
            {
                measure_direction_type = CHILD_TO_PARENT;
            }
            else
            {
                std::cerr<< "[ERROR] sensor " << sensorName
                         << " of type force_torque has unexpected measure_direction content " << measure_direction
                         << ", parsing failed." << std::endl;
                parsingSuccessful = false;
                return false;
            }

            // Get parent and child links of the joint to which the FT sensor is attached
            std::string parentLinkName, childLinkName;
            bool ok = findJointParentsAndChild(robotXml,parentJoint,parentLinkName,childLinkName);

            if( !ok )
            {
                parsingSuccessful = false;
                return false;
            }

            LinkIndex parentLinkIndex = model.getLinkIndex(parentLinkName);
            LinkIndex childLinkIndex  = model.getLinkIndex(childLinkName);

            if( parentLinkIndex == LINK_INVALID_INDEX ||
                childLinkIndex  == LINK_INVALID_INDEX )
            {
                std::cerr<< "[ERROR] link " << parentLinkName << " or " << childLinkName
                         << " not found when parsing sensor " << sensorName
                         << ", parsing failed." << std::endl;
                parsingSuccessful = false;
                return false;
            }

            SixAxisForceTorqueSensor * sensor = new SixAxisForceTorqueSensor();
            sensor->setName(sensorName);
            sensor->setParentJoint(parentJoint);
            sensor->setParentJointIndex(parentLinkIndex);
            if( measure_direction_type == PARENT_TO_CHILD )
            {
                sensor->setAppliedWrenchLink(childLinkIndex);
            }
            else
            {
                sensor->setAppliedWrenchLink(parentLinkIndex);
            }

            // The transform tag is parsed using the Gazebo convention
            // For now we assume that the six axis ft sensor is attached to a
            // fixed junction. Hence the first/second link to sensor transforms
            // are fixed are given by the frame option
            iDynTree::Transform parent_link_H_child_link = model.getJoint(parentJointIndex)->getRestTransform(parentLinkIndex,childLinkIndex);
            iDynTree::Transform child_link_H_sensor = link_H_pose;

            if( frame_type == PARENT_LINK_FRAME )
            {
                sensor->setFirstLinkSensorTransform(parentLinkIndex,iDynTree::Transform::Identity());
                sensor->setSecondLinkSensorTransform(childLinkIndex,parent_link_H_child_link.inverse());
            }
            else if( frame_type == CHILD_LINK_FRAME )
            {
                sensor->setFirstLinkSensorTransform(parentLinkIndex,parent_link_H_child_link);
                sensor->setSecondLinkSensorTransform(childLinkIndex,iDynTree::Transform::Identity());
            }
            else
            {
                assert( frame_type == SENSOR_FRAME );
                sensor->setFirstLinkSensorTransform(parentLinkIndex,parent_link_H_child_link*child_link_H_sensor);
                sensor->setSecondLinkSensorTransform(childLinkIndex,child_link_H_sensor);
            }

            sensor->setFirstLinkName(parentLinkName);
            sensor->setSecondLinkName(childLinkName);

            newSensors.addSensor(*sensor);
            delete sensor;
        }
        else if( type == GYROSCOPE )
        {
            GyroscopeSensor * sensor = new GyroscopeSensor();
            sensor->setLinkSensorTransform(link_H_pose);
            sensor->setName(sensorName);
            sensor->setParentLink(parentLink);
            sensor->setParentLinkIndex(parentLinkIndex);
            newSensors.addSensor(*sensor);
            delete sensor;
        }
        else if( type == ACCELEROMETER )
        {
            AccelerometerSensor * sensor = new AccelerometerSensor();
            sensor->setLinkSensorTransform(link_H_pose);
            sensor->setName(sensorName);
            sensor->setParentLink(parentLink);
            sensor->setParentLinkIndex(parentLinkIndex);
            newSensors.addSensor(*sensor);
            delete sensor;
        }
        else
        {
           std::cerr<< "[ERROR] sensor " << sensorName
                         << " of unknown type "
                         << ", parsing failed." << std::endl;
           parsingSuccessful = false;
           return false;
        }

    }

    // If the parsing was successful,
    // copy the obtained sensors to the output structure
    if( parsingSuccessful )
    {
        outputSensors = newSensors;
    }

    return parsingSuccessful;
}
int main()
{
    // Load data
    std::string fileName = getAbsModelPath("icub_sensorised.urdf");
    Model fullModel = getModel(fileName);
    SensorsList fullSensors = getSensors(fileName);

    // Store data for a given FT sensor
    DataFT dataFT_l_leg;
    dataFT_l_leg.jointName = "l_leg_ft_sensor";
    // Links
    dataFT_l_leg.parent_linkName = "l_hip_2";
    dataFT_l_leg.child_linkName = "l_hip_3";
    dataFT_l_leg.grandparent_linkName = "l_hip_1";
    dataFT_l_leg.grandchild_linkName = "l_upper_leg";
    // Joints
    dataFT_l_leg.grandparentToParent_jointName = "l_hip_roll";
    dataFT_l_leg.childToGranchild_jointName = "l_hip_yaw";

    // Get all the iCub joints
    vector<string> fullJoints = get_iCubJointsSensorised();

    // Keep only one FT
    vector<string> removedJoints;
    removedJoints.push_back("r_leg_ft_sensor");
    removedJoints.push_back("l_foot_ft_sensor");
    removedJoints.push_back("r_foot_ft_sensor");
    removedJoints.push_back("l_arm_ft_sensor");
    removedJoints.push_back("r_arm_ft_sensor");
    vector<string> fullJoints_1FT = removeJoints(fullJoints, removedJoints);

    // Setup the experiments
    // ---------------------

    // 1) The reduced model doesn't lump links which the FT is connected
    ExperimentFT test_defaultModel;
    test_defaultModel.dataFT = dataFT_l_leg;
    test_defaultModel.expectedFirstLinkName = dataFT_l_leg.parent_linkName;
    test_defaultModel.expectedSecondLinkName = dataFT_l_leg.child_linkName;

    // 2) The reduced model doesn't contain the firstLink
    ExperimentFT test_removeFirstLink;
    test_removeFirstLink.dataFT = dataFT_l_leg;
    test_removeFirstLink.removedJoints.push_back(test_removeFirstLink.dataFT.grandparentToParent_jointName);
    test_removeFirstLink.expectedFirstLinkName = dataFT_l_leg.grandparent_linkName;
    test_removeFirstLink.expectedSecondLinkName = dataFT_l_leg.child_linkName;

    // 3) The reduced model doesn't contain the secondLink
    ExperimentFT test_removeSecondLink;
    test_removeSecondLink.dataFT = dataFT_l_leg;
    test_removeSecondLink.removedJoints.push_back(test_removeSecondLink.dataFT.childToGranchild_jointName);
    test_removeSecondLink.expectedFirstLinkName = dataFT_l_leg.parent_linkName;
    test_removeSecondLink.expectedSecondLinkName = dataFT_l_leg.child_linkName;

    // 3) The reduced model doesn't contain both firstLink and secondLink
    ExperimentFT test_removeFirstAndSecondLink;
    test_removeFirstAndSecondLink.dataFT = dataFT_l_leg;
    test_removeFirstAndSecondLink.removedJoints.push_back(test_removeFirstAndSecondLink.dataFT.grandparentToParent_jointName);
    test_removeFirstAndSecondLink.removedJoints.push_back(test_removeFirstAndSecondLink.dataFT.childToGranchild_jointName);
    test_removeFirstAndSecondLink.expectedFirstLinkName = dataFT_l_leg.grandparent_linkName;
    test_removeFirstAndSecondLink.expectedSecondLinkName = dataFT_l_leg.child_linkName;

    // Group all the experiments together
    vector<ExperimentFT> experiments;
    experiments.push_back(test_defaultModel);
    experiments.push_back(test_removeFirstLink);
    experiments.push_back(test_removeSecondLink);
    experiments.push_back(test_removeFirstAndSecondLink);

    for (auto experiment : experiments)
    {
        bool ok;

        Model reducedModel;
        SensorsList reducedSensors;

        ok = createReducedModelAndSensors(fullModel,
                                          fullSensors,
                                          removeJoints(fullJoints_1FT, experiment.removedJoints),
                                          reducedModel,
                                          reducedSensors);
        ASSERT_IS_TRUE(ok);
        ASSERT_EQUAL_DOUBLE(reducedSensors.getNrOfSensors(SIX_AXIS_FORCE_TORQUE), 1);

        Sensor* s = reducedSensors.getSensor(SIX_AXIS_FORCE_TORQUE, 0);
        ASSERT_IS_TRUE(s != nullptr);
        ASSERT_IS_TRUE(s->isValid());

        JointSensor* jointSens = dynamic_cast<JointSensor*>(s);
        ASSERT_IS_TRUE(jointSens != nullptr);

        unique_ptr<SixAxisForceTorqueSensor> sensorCopy;
        sensorCopy.reset(static_cast<SixAxisForceTorqueSensor*>(jointSens->clone()));
        ASSERT_IS_TRUE(sensorCopy != nullptr);

        printFT(*sensorCopy);
        cout << endl;

        ASSERT_EQUAL_STRING(sensorCopy->getFirstLinkName(), experiment.expectedFirstLinkName);
        ASSERT_EQUAL_STRING(sensorCopy->getSecondLinkName(), experiment.expectedSecondLinkName);

        // Test transform
        // --------------

        // Get the transform from the fixed joint.
        // It uses the createReducedModel() logic. It is used as ground truth.
        Transform parent_H_child;
        auto jointFT = reducedModel.getJoint(reducedModel.getJointIndex(experiment.dataFT.jointName));
        parent_H_child = jointFT->getRestTransform(jointFT->getFirstAttachedLink(),
                                                   jointFT->getSecondAttachedLink());

        // Get the transform from the sensor.
        // This is calculated by createReducedModelAndSensors() and it is the method under test.
        LinkIndex firstLinkIndex = sensorCopy->getFirstLinkIndex();
        LinkIndex secondLinkIndex = sensorCopy->getSecondLinkIndex();
        Transform firstLink_H_sensorFrame;
        Transform secondLink_H_sensorFrame;
        ok = true;
        ok = ok && sensorCopy->getLinkSensorTransform(firstLinkIndex,  firstLink_H_sensorFrame);
        ok = ok && sensorCopy->getLinkSensorTransform(secondLinkIndex, secondLink_H_sensorFrame);
        ASSERT_IS_TRUE(ok);

        ASSERT_EQUAL_TRANSFORM(parent_H_child,
                               firstLink_H_sensorFrame*secondLink_H_sensorFrame.inverse());
    }

    return EXIT_SUCCESS;
}