Example #1
0
/**
*  \brief  This function runs pd_control on motor position.
*  \param device0 robot_device struct defined in DS0.h
*  \param currParams param_pass struct defined in DS1.h
*  \return -1 if Pedal is up and 0 when torque is applied to DAC
*
* This function:
*  1. calls the r2_inv_kin() to calculate the inverse kinematics
*  2. call the invCableCoupling() to calculate the inverse cable coupling
*  3. set all the joints to zero if pedal is not down otherwise it calls mpos_PD_control() to run the PD control law
*  4. calls getGravityTorque() to calulate gravity torques on each joints.
*  5. calls TorqueToDAC() to apply write torque value's on DAC
* 
*/
int raven_cartesian_space_command(struct device *device0, struct param_pass *currParams){

    struct DOF *_joint = NULL;
    struct mechanism* _mech = NULL;
    int i=0,j=0;

    if (currParams->runlevel < RL_PEDAL_UP)
    {
    	return -1;
    }
    else if (currParams->runlevel < RL_PEDAL_DN)
    {
    	set_posd_to_pos(device0);
    	updateMasterRelativeOrigin(device0);
    }

    parport_out(0x01);

    //Inverse kinematics
    r2_inv_kin(device0, currParams->runlevel);

    //Inverse Cable Coupling
    invCableCoupling(device0, currParams->runlevel);

    // Set all joints to zero torque
    _mech = NULL;  _joint = NULL;
    while (loop_over_joints(device0, _mech, _joint, i,j) )
    {
        if (currParams->runlevel != RL_PEDAL_DN)
        {
            _joint->tau_d=0;
        }
        else
        {
    	    mpos_PD_control(_joint);
        }
    }

    // Gravity compensation calculation
    getGravityTorque(*device0, *currParams);
    _mech = NULL;  _joint = NULL;
    while ( loop_over_joints(device0, _mech, _joint, i,j) )
    {
        _joint->tau_d += _joint->tau_g;  // Add gravity torque
    }

    TorqueToDAC(device0);

    return 0;
}
Example #2
0
/**
*  \brief Implements control for one loop cycle.
*
* \post encoders values have been read, runlevel has been set
* \pre robot state is reflected in device0, DAC outputs are set in device0
*
* \brief This funtion controls the Raven based on the desired control mode.
* \param device0 robot_device struct defined in DS0.h
* \param currParam param_pass struct defined in DS1.h
*
* This function first initializes the robot and then it computes Mpos and Velocities by calling
* stateEstimate() and then it calls fwdCableCoupling() and r2_fwd_kin() to calculate the forward cable coupling
* inverse kinematics respectively. 
* The following types of control can be selected from the control mode:
*  -No control
*  -Cartesian Space Control
*  -Motor PD Control
*  -Joint Velocity Control
*  -Homing mode
*  -Applying arbitrary torque
*
*/
int controlRaven(struct device *device0, struct param_pass *currParams){
    int ret = 0;
    //Desired control mode
    t_controlmode controlmode = (t_controlmode)currParams->robotControlMode;

    //Initialization code
    initRobotData(device0, currParams->runlevel, currParams);

    //Compute Mpos & Velocities
    stateEstimate(device0);

    //Foward Cable Coupling
    fwdCableCoupling(device0, currParams->runlevel);

    //Forward kinematics
    r2_fwd_kin(device0, currParams->runlevel);

    switch (controlmode){

        //CHECK ME: what is the purpose of this mode?
        case no_control:
        {
            initialized = false;

            struct DOF *_joint = NULL;
            struct mechanism* _mech = NULL;
            int i=0,j=0;

            // Gravity compensation calculation
            getGravityTorque(*device0, *currParams);

            while ( loop_over_joints(device0, _mech, _joint, i,j) )
                _joint->tau_d = _joint->tau_g;  // Add gravity torque

            TorqueToDAC(device0);

        	break;
        }
        //Cartesian Space Control is called to control the robot in cartesian space
        case cartesian_space_control:
        	ret = raven_cartesian_space_command(device0,currParams);
        	break;
        //Motor PD control runs PD control on motor position
        case motor_pd_control:
            initialized = false;
            ret = raven_motor_position_control(device0,currParams);
            break;
        //Runs joint velocity control
        case joint_velocity_control:
            initialized = false;
            ret = raven_joint_velocity_control(device0, currParams);
            break;
        //Runs homing mode
        case homing_mode:
        	static int hom = 0;
        	if (hom==0){
        		log_msg("Entered homing mode");
        		hom = 1;
        	}
            initialized = false;
            //initialized = robot_ready(device0) ? true:false;
            ret = raven_homing(device0, currParams);
            set_posd_to_pos(device0);
            updateMasterRelativeOrigin(device0);

            if (robot_ready(device0))
            {
                currParams->robotControlMode = cartesian_space_control;
                newRobotControlMode = cartesian_space_control;
            }
            break;
	//Runs applyTorque() to set torque command (tau_d) to a joint for debugging purposes
        case apply_arbitrary_torque:
            initialized = false;
            ret = applyTorque(device0, currParams);
            break;
	//Apply sinusoidal trajectory to all joints
        case multi_dof_sinusoid:
            initialized = false;
            ret = raven_sinusoidal_joint_motion(device0, currParams);
            break;

        default:
            ROS_ERROR("Error: unknown control mode in controlRaven (rt_raven.cpp)");
            ret = -1;
            break;
    }

    return ret;
}
void JtATIController::updateHook()
{
    if(use_ft_sensor && port_ftdata.read(wrench_msg) != RTT::NewData)
        return;
    
    if(!updateState()) return;
    
    jnt_trq_cmd.setZero();
    
    if(0)
    {
        getMassMatrix(mass);
        
        id_dyn_solver->JntToMass(jnt_pos_kdl,mass_kdl);
        
        RTT::log(RTT::Warning) << "mass : \n"<<mass<<RTT::endlog();
        RTT::log(RTT::Warning) << "mass_kdl : \n"<<mass_kdl.data<<RTT::endlog();
    }
    

    if(use_ft_sensor){
        if(use_kdl){
            // remove B(q,qdot)
            jnt_vel_kdl.data.setZero();
            // Get the Wrench in the last segment's frame
            tf::wrenchMsgToKDL(wrench_msg.wrench,wrench_kdl);
            f_ext_kdl.back() = wrench_kdl;
            // Get The full dynamics with external forces
            id_rne_solver->CartToJnt(jnt_pos_kdl,jnt_vel_kdl,jnt_acc_kdl,f_ext_kdl,jnt_trq_kdl);
            // Get Joint Gravity torque
            id_dyn_solver->JntToGravity(jnt_pos_kdl,gravity_kdl);
            // remove G(q)
            jnt_trq_cmd = jnt_trq_kdl.data - gravity_kdl.data;
            RTT::log(RTT::Debug) << "Adding FT data    : \n"<<jnt_trq_cmd.transpose()<<RTT::endlog();
        
        }else{
            // Get Jacobian with KRC
            getJacobian(J_tip_base);
            getCartesianPosition(cart_pos);
            tf::poseMsgToKDL(cart_pos,tool_in_base_frame);
            tf::poseMsgToEigen(cart_pos,tool_in_base_frame_eigen);
            J_tip_base.changeBase(tool_in_base_frame.M);
            
            RTT::log(RTT::Debug) << "J : \n"<<J_tip_base.data<<RTT::endlog();
            
            
            // Get Jacobian with KDL
            jnt_to_jac_solver->JntToJac(jnt_pos_kdl,J_kdl,kdl_chain.getNrOfSegments());
            
            RTT::log(RTT::Debug) << "J_kdl : \n"<<J_kdl.data<<RTT::endlog();
            
            tf::wrenchMsgToEigen(wrench_msg.wrench,wrench);
            //tf::wrenchMsgToKDL(wrench_msg.wrench,wrench_kdl);
            wrench_kdl = tool_in_base_frame.M * wrench_kdl;
            ///tf::wrenchKDLToEigen(wrench_kdl,wrench);
            jnt_trq_cmd = J_tip_base.data.transpose() * wrench;
        
        }
    }
    
    if(use_kdl_gravity)
    {
        getGravityTorque(jnt_grav);
        id_dyn_solver->JntToGravity(jnt_pos_kdl,gravity_kdl);
        jnt_trq_cmd += kg.asDiagonal() * gravity_kdl.data - jnt_grav;
        RTT::log(RTT::Debug) << "Adding gravity    : \n"<<(kg.asDiagonal() * gravity_kdl.data - jnt_grav).transpose()<<RTT::endlog();
    }
    
    if(compensate_coriolis)
    {
        id_dyn_solver->JntToCoriolis(jnt_pos_kdl,jnt_vel_kdl,coriolis_kdl);
        jnt_trq_cmd -= coriolis_kdl.data.asDiagonal()*jnt_vel;
        RTT::log(RTT::Debug) << "Removing Coriolis    : \n"<<(coriolis_kdl.data.asDiagonal()*jnt_vel).transpose()<<RTT::endlog();
    }
    
    if(add_damping)
    {
        jnt_trq_cmd -= kd.asDiagonal() * jnt_vel;
        RTT::log(RTT::Debug) << "Adding damping    : \n"<<-(kd.asDiagonal() * jnt_vel).transpose()<<RTT::endlog();
    }

    RTT::log(RTT::Debug) << "jnt_trq_cmd    : \n"<<jnt_trq_cmd.transpose()<<RTT::endlog(); 

    sendJointTorque(jnt_trq_cmd);
}