///does the commutation of the arm joints with firmware 1.48 and below
void YouBotManipulator::commutationFirmware148() {
  // Bouml preserved body begin 0010D971
  
    InitializeJoint doInitialization;
    bool isInitialized = false;
    int noInitialization = 0;
    std::string jointName;


    ClearMotorControllerTimeoutFlag clearTimeoutFlag;
    for (unsigned int i = 1; i <= numberArmJoints; i++) {
      this->getArmJoint(i).setConfigurationParameter(clearTimeoutFlag);
    }

    for (unsigned int i = 1; i <= numberArmJoints; i++) {
      doInitialization.setParameter(false);
      this->getArmJoint(i).getConfigurationParameter(doInitialization);
      doInitialization.getParameter(isInitialized);
      if (!isInitialized) {
        noInitialization++;
      }
    }

    if (noInitialization != 0) {
      LOG(info) << "Manipulator Joint Commutation";
      doInitialization.setParameter(true);

      ethercatMaster.AutomaticReceiveOn(false);
      for (unsigned int i = 1; i <= numberArmJoints; i++)
          this->getArmJoint(i).setConfigurationParameter(doInitialization);
      ethercatMaster.AutomaticReceiveOn(true);

      unsigned int statusFlags;
      std::vector<bool> isCommutated;
      isCommutated.assign(numberArmJoints, false);
      unsigned int u = 0;

      // check for the next 5 sec if the joints are commutated
      for (u = 1; u <= 5000; u++) {
        for (unsigned int i = 1; i <= numberArmJoints; i++) {
          if(!ethercatMaster.isThreadActive()){
            ethercatMaster.sendProcessData();
            ethercatMaster.receiveProcessData();
          }
          this->getArmJoint(i).getStatus(statusFlags);
          if (statusFlags & INITIALIZED) {
            isCommutated[i - 1] = true;
          }
        }
        if (isCommutated[0] && isCommutated[1] && isCommutated[2] && isCommutated[3] && isCommutated[4]) {
          break;
        }
        SLEEP_MILLISEC(1);
      }

      SLEEP_MILLISEC(10); // the controller likes it

      for (unsigned int i = 1; i <= numberArmJoints; i++) {
        doInitialization.setParameter(false);
        this->getArmJoint(i).getConfigurationParameter(doInitialization);
        doInitialization.getParameter(isInitialized);
        if (!isInitialized) {
          std::stringstream jointNameStream;
          jointNameStream << "manipulator joint " << i;
          jointName = jointNameStream.str();
          throw std::runtime_error("Could not commutate " + jointName);
        }
      }
    }


  // Bouml preserved body end 0010D971
}
Esempio n. 2
0
///establishes the ethercat connection
void EthercatMaster::initializeEthercat() {
  // Bouml preserved body begin 000410F1

    /* initialise SOEM, bind socket to ifname */
    if (ec_init(ethernetDevice.c_str())) {
      LOG(info) << "Initializing EtherCAT on " << ethernetDevice;
      /* find and auto-config slaves */
      if (ec_config(TRUE, &IOmap_) > 0) {

        LOG(trace) << ec_slavecount << " slaves found and configured.";

        /* wait for all slaves to reach Pre OP state */
        /*ec_statecheck(0, EC_STATE_PRE_OP,  EC_TIMEOUTSTATE);
        if (ec_slave[0].state != EC_STATE_PRE_OP ){
        printf("Not all slaves reached pre operational state.\n");
        ec_readstate();
        //If not all slaves operational find out which one
          for(int i = 1; i<=ec_slavecount ; i++){
            if(ec_slave[i].state != EC_STATE_PRE_OP){
              printf("Slave %d State=%2x StatusCode=%4x : %s\n",
              i, ec_slave[i].state, ec_slave[i].ALstatuscode, ec_ALstatuscode2string(ec_slave[i].ALstatuscode));
            }
          }
        }
         */

        /* distributed clock is not working
        //Configure distributed clock
        if(!ec_configdc()){
          LOG(warning) << "no distributed clock is available";
        }else{

          uint32 CyclTime = 4000000;
          uint32 CyclShift = 0;
          for (int i = 1; i <= ec_slavecount; i++) {
            ec_dcsync0(i, true, CyclTime, CyclShift);
          }

        }
         */

        /* wait for all slaves to reach SAFE_OP state */
        ec_statecheck(0, EC_STATE_SAFE_OP, EC_TIMEOUTSTATE);
        if (ec_slave[0].state != EC_STATE_SAFE_OP) {
          LOG(warning) << "Not all slaves reached safe operational state.";
          ec_readstate();
          //If not all slaves operational find out which one
          for (int i = 1; i <= ec_slavecount; i++) {
            if (ec_slave[i].state != EC_STATE_SAFE_OP) {
              LOG(info) << "Slave " << i << " State=" << ec_slave[i].state << " StatusCode=" << ec_slave[i].ALstatuscode << " : " << ec_ALstatuscode2string(ec_slave[i].ALstatuscode);

            }
          }
        }


        //Read the state of all slaves
        //ec_readstate();

        LOG(trace) << "Request operational state for all slaves";

        ec_slave[0].state = EC_STATE_OPERATIONAL;
        // request OP state for all slaves
        /* send one valid process data to make outputs in slaves happy*/
        ec_send_processdata();
        ec_receive_processdata(EC_TIMEOUTRET);
        /* request OP state for all slaves */
        ec_writestate(0);
        // wait for all slaves to reach OP state

        ec_statecheck(0, EC_STATE_OPERATIONAL, EC_TIMEOUTSTATE);
        if (ec_slave[0].state == EC_STATE_OPERATIONAL) {
          LOG(trace) << "Operational state reached for all slaves.";
        } else {
          throw std::runtime_error("Not all slaves reached operational state.");

        }

      } else {
        throw std::runtime_error("No slaves found!");
      }

    } else {
      throw std::runtime_error("No socket connection on " + ethernetDevice + "\nExcecute as root");
    }



    std::string baseJointControllerName = "TMCM-174";
    std::string manipulatorJointControllerName = "TMCM-174";
    std::string actualSlaveName;
    nrOfSlaves = 0;
    YouBotSlaveMsg emptySlaveMsg;
    quantity<si::current> maxContinuousCurrentBase = 3.54 * ampere;
    quantity<si::time> thermalTimeConstantWindingBase = 16.6 * second;
    quantity<si::time> thermalTimeConstantMotorBase = 212 * second;
    quantity<si::current> maxContinuousCurrentJoint13 = 2.36 * ampere;
    quantity<si::time> thermalTimeConstantWindingJoint13 = 16.6 * second;
    quantity<si::time> thermalTimeConstantMotorJoint13 = 212 * second;
    quantity<si::current> maxContinuousCurrentJoint4 = 1.07 * ampere;
    quantity<si::time> thermalTimeConstantWindingJoint4 = 13.2 * second;
    quantity<si::time> thermalTimeConstantMotorJoint4 = 186 * second;
    quantity<si::current> maxContinuousCurrentJoint5 = 0.49 * ampere;
    quantity<si::time> thermalTimeConstantWindingJoint5 = 8.1 * second;
    quantity<si::time> thermalTimeConstantMotorJoint5 = 108 * second;
    int manipulatorNo = 0;


    configfile->readInto(baseJointControllerName, "BaseJointControllerName");
    configfile->readInto(manipulatorJointControllerName, "ManipulatorJointControllerName");

    //reserve memory for all slave with a input/output buffer
    for (int cnt = 1; cnt <= ec_slavecount; cnt++) {
      //     printf("Slave:%d Name:%s Output size:%3dbits Input size:%3dbits State:%2d delay:%d.%d\n",
      //             cnt, ec_slave[cnt].name, ec_slave[cnt].Obits, ec_slave[cnt].Ibits,
      //             ec_slave[cnt].state, (int) ec_slave[cnt].pdelay, ec_slave[cnt].hasdc);

      ethercatSlaveInfo.push_back(ec_slave[cnt]);

      actualSlaveName = ec_slave[cnt].name;
      if ((actualSlaveName == baseJointControllerName || actualSlaveName == manipulatorJointControllerName) && ec_slave[cnt].Obits > 0 && ec_slave[cnt].Ibits > 0) {
        nrOfSlaves++;
        //   joints.push_back(YouBotJoint(nrOfSlaves));

        firstBufferVector.push_back(emptySlaveMsg);
        secondBufferVector.push_back(emptySlaveMsg);
        ethercatOutputBufferVector.push_back((SlaveMessageOutput*) (ec_slave[cnt].outputs));
        ethercatInputBufferVector.push_back((SlaveMessageInput*) (ec_slave[cnt].inputs));
        YouBotSlaveMailboxMsg emptyMailboxSlaveMsg(cnt);
        firstMailboxBufferVector.push_back(emptyMailboxSlaveMsg);
        secondMailboxBufferVector.push_back(emptyMailboxSlaveMsg);
        newOutputDataFlagOne.push_back(false);
        newOutputDataFlagTwo.push_back(false);
        newMailboxDataFlagOne.push_back(false);
        newMailboxDataFlagTwo.push_back(false);
        newMailboxInputDataFlagOne.push_back(false);
        newMailboxInputDataFlagTwo.push_back(false);
        pendingMailboxMsgsReply.push_back(false);
        int i = 0;
        bool b = false;
        upperLimit.push_back(i);
        lowerLimit.push_back(i);
        limitActive.push_back(b);
        jointLimitReached.push_back(b);
        inverseMovementDirection.push_back(b);
        if (actualSlaveName == baseJointControllerName) {
          motorProtections.push_back(MotorProtection(maxContinuousCurrentBase,
                  thermalTimeConstantWindingBase,
                  thermalTimeConstantMotorBase));
        }
        if (actualSlaveName == manipulatorJointControllerName) {
          manipulatorNo++;
          if (manipulatorNo >= 1 && manipulatorNo <= 3) {
            motorProtections.push_back(MotorProtection(maxContinuousCurrentJoint13,
                    thermalTimeConstantWindingJoint13,
                    thermalTimeConstantMotorJoint13));
          }
          if (manipulatorNo == 4) {
            motorProtections.push_back(MotorProtection(maxContinuousCurrentJoint4,
                    thermalTimeConstantWindingJoint4,
                    thermalTimeConstantMotorJoint4));
          }
          if (manipulatorNo == 5) {
            motorProtections.push_back(MotorProtection(maxContinuousCurrentJoint5,
                    thermalTimeConstantWindingJoint5,
                    thermalTimeConstantMotorJoint5));
            manipulatorNo = 0;
          }

        }
      }

    }
    if (nrOfSlaves != motorProtections.size()) {
      throw std::runtime_error("Insufficient motor protections loaded");
    }

    if (nrOfSlaves > 0) {
      LOG(info) << nrOfSlaves << " EtherCAT slaves found" ;
    } else {
      throw std::runtime_error("No EtherCAT slave could be found");
      return;
    }

    stopThread = false;
    threads.create_thread(boost::bind(&EthercatMaster::updateSensorActorValues, this));

    SLEEP_MILLISEC(10); //needed to start up thread and EtherCAT communication

    return;
  // Bouml preserved body end 000410F1
}
///calibrate the reference position of the arm joints
void YouBotManipulator::calibrateManipulator(const bool forceCalibration) {
  // Bouml preserved body begin 000A9C71

    //Calibrate all manipulator joints
    std::vector<JointRoundsPerMinuteSetpoint> calibrationVel;
    JointRoundsPerMinuteSetpoint tempdummy;
    tempdummy.rpm = 0;
    calibrationVel.assign(numberArmJoints, tempdummy);
    std::vector<quantity<si::current> > maxCurrent;
    quantity<si::current> tempdummy2;
    maxCurrent.assign(numberArmJoints, tempdummy2);
    std::vector<bool> doCalibration;
    doCalibration.assign(numberArmJoints, true);
    std::string jointName;

    double dummy = 0;
    char index = 16; // Parameter 0 to 15 of bank 2 are password protected

    YouBotSlaveMailboxMsg IsCalibratedReadMessage;
    IsCalibratedReadMessage.stctOutput.moduleAddress = DRIVE;
    IsCalibratedReadMessage.stctOutput.commandNumber = GGP;
    IsCalibratedReadMessage.stctOutput.typeNumber = index;
    IsCalibratedReadMessage.stctOutput.motorNumber = USER_VARIABLE_BANK;
    IsCalibratedReadMessage.stctOutput.value = 0;
    IsCalibratedReadMessage.stctInput.value = 0;

    YouBotSlaveMailboxMsg IsCalibratedSetMessage;
    IsCalibratedSetMessage.stctOutput.moduleAddress = DRIVE;
    IsCalibratedSetMessage.stctOutput.commandNumber = SGP;
    IsCalibratedSetMessage.stctOutput.typeNumber = index;
    IsCalibratedSetMessage.stctOutput.motorNumber = USER_VARIABLE_BANK;
    IsCalibratedSetMessage.stctOutput.value = 1;


    //get parameters for calibration
    for (unsigned int i = 0; i < numberArmJoints; i++) {

      std::stringstream jointNameStream;
      jointNameStream << "Joint_" << i + 1;
      jointName = jointNameStream.str();
      bool calib = true;
      configfile->readInto(calib, jointName, "DoCalibration");
      doCalibration[i] = calib;

      joints[i].getConfigurationParameter(IsCalibratedReadMessage);
      if (IsCalibratedReadMessage.stctInput.value == 1) {
        doCalibration[i] = false;
      }

      if (forceCalibration) {
        doCalibration[i] = true;
      }

      configfile->readInto(dummy, jointName, "CalibrationMaxCurrent_[ampere]");
      maxCurrent[i] = dummy * ampere;
      std::string direction;
      configfile->readInto(direction, jointName, "CalibrationDirection");
      GearRatio gearRatio;
      joints[i].getConfigurationParameter(gearRatio);
      double gearratio = 1;
      gearRatio.getParameter(gearratio);

      if (direction == "POSITIV") {
        calibrationVel[i].rpm = 1 / gearratio;
      } else if (direction == "NEGATIV") {
        calibrationVel[i].rpm = -1 / gearratio;
      } else {
        throw std::runtime_error("Wrong calibration direction for " + jointName);
      }
    }


    LOG(info) << "Calibrate Manipulator Joints ";

    std::vector<bool> finished;
    finished.assign(numberArmJoints, false);
    int numberUnfinished = numberArmJoints;
    JointSensedCurrent sensedCurrent;


    //move the joints slowly in calibration direction
    for (unsigned int i = 0; i < numberArmJoints; i++) {
      if (doCalibration[i] == true) {
        joints[i].setData(calibrationVel[i]);
        if(!ethercatMaster.isThreadActive()){
          ethercatMaster.sendProcessData();
          ethercatMaster.receiveProcessData();
        }
      } else {
        if (!finished[i]) {
            finished[i] = true;
            numberUnfinished--;
        }
      }
    }

    //monitor the current to find end stop 
    while (numberUnfinished > 0) {
      for (unsigned int i = 0; i < numberArmJoints; i++) {
        if(!ethercatMaster.isThreadActive()){
          ethercatMaster.sendProcessData();
          ethercatMaster.receiveProcessData();
        }
        joints[i].getData(sensedCurrent);
        //turn till a max current is reached
        if (abs(sensedCurrent.current) > abs(maxCurrent[i])) {
          //stop movement
          youbot::JointCurrentSetpoint currentStopMovement;
          currentStopMovement.current = 0 * ampere;
          joints[i].setData(currentStopMovement);
          if(!ethercatMaster.isThreadActive()){
            ethercatMaster.sendProcessData();
            ethercatMaster.receiveProcessData();
          }
          if (!finished[i]) {
              finished[i] = true;
              numberUnfinished--;
          }
        }
      }
      SLEEP_MILLISEC(1);
    }

    // wait to let the joint stop the motion
    SLEEP_MILLISEC(100);

    for (unsigned int i = 0; i < numberArmJoints; i++) {
      if (doCalibration[i] == true) {
        //set encoder reference position
        joints[i].setEncoderToZero();
        if(!ethercatMaster.isThreadActive()){
          ethercatMaster.sendProcessData();
          ethercatMaster.receiveProcessData();
        }
        // set a flag in the user variable to remember that it is calibrated
        joints[i].setConfigurationParameter(IsCalibratedSetMessage);
        //     LOG(info) << "Calibration finished for joint: " << this->jointName;
      }
    }

    //setting joint Limits
    JointLimits jLimits;
    for (unsigned int i = 0; i < numberArmJoints; i++) {
      long upperlimit = 0, lowerlimit = 0;
      std::stringstream jointNameStream;
      bool inverted = false;
      jointNameStream << "Joint_" << i + 1;
      jointName = jointNameStream.str();
      JointEncoderSetpoint minEncoderValue;
      configfile->readInto(lowerlimit, jointName, "LowerLimit_[encoderTicks]");
      configfile->readInto(upperlimit, jointName, "UpperLimit_[encoderTicks]");
      configfile->readInto(inverted, jointName, "InverseMovementDirection");
      
      if(inverted){
        minEncoderValue.encoderTicks = lowerlimit + 1000;
      }else{
        minEncoderValue.encoderTicks = upperlimit - 1000;
      }

      jLimits.setParameter(lowerlimit, upperlimit, true);
      joints[i].setConfigurationParameter(jLimits);
     // joints[i].setData(minEncoderValue);
    }

  // Bouml preserved body end 000A9C71
}