/*!
 * \brief Returns the current states
 */
bool PowerCubeCtrl::updateStates()
{
	PCTRL_CHECK_INITIALIZED();

	unsigned int DOF = m_params->GetDOF();

	unsigned long state;
	unsigned char dio;
	float position;
	int ret = 0;
	for (unsigned int i = 0; i < DOF; i++)
	{
		pthread_mutex_lock(&m_mutex);
		ret = PCube_getStateDioPos(m_DeviceHandle, m_params->GetModuleID(i), &state, &dio, &position);
		pthread_mutex_unlock(&m_mutex);
		
		if (ret != 0)
		{
			m_pc_status = PC_CTRL_ERR;
		}

		m_status[i] = state;
		m_dios[i] = dio;
		m_positions[i] = position;

    /// ToDo: calculate vel and acc
    ///m_velocities = ???;
    ///m_accelerations = ???
	}
	
	return true;
}
示例#2
0
/// @brief Returns the current states
bool PowerCubeCtrl::updateStates()
{
  PCTRL_CHECK_INITIALIZED();

  unsigned int DOF = m_params->GetDOF();

  unsigned long state;
  unsigned char dio;
  float position;
  for (unsigned int i = 0; i < DOF; i++)
  {
    pthread_mutex_lock(&m_mutex);
    //std::cout << "------------------------------> PCube_getStateDioPos()" << std::endl;
    PCube_getStateDioPos(m_DeviceHandle, m_params->GetModuleID(i), &state, &dio, &position);
    pthread_mutex_unlock(&m_mutex);

    m_status[i] = state;
    m_dios[i] = dio;
    m_positions[i] = position;
    
    // @todo calculate vel and acc
    //m_velocities = ???;
    //m_accelerations = ???
  }

  return true;
}
/*!
 * \brief Returns true if some cubes are still moving
 */
bool PowerCubeCtrl::statusMoving()
{
	PCTRL_CHECK_INITIALIZED();

	for (int i = 0; i < m_params->GetDOF(); i++)
	{
		if (m_status[i] & STATEID_MOD_MOTION)
			return true;
	}
	return false;
}
/*!
 * \brief Sets the maximum angular acceleration (rad/s^2) for the Joints, use with care!
 */
bool PowerCubeCtrl::setMaxAcceleration(const std::vector<double>& maxAccelerations)
{
	PCTRL_CHECK_INITIALIZED();

	for (int i = 0; i < m_params->GetDOF(); i++)
	{
		pthread_mutex_lock(&m_mutex);
		PCube_setMaxAcc(m_DeviceHandle, m_params->GetModuleID(i), maxAccelerations[i]);
		pthread_mutex_unlock(&m_mutex);
		m_params->SetMaxAcc(maxAccelerations);
	}

	return true;
}
/*!
 * \brief Sets the maximum angular velocity (rad/s) for the Joints, use with care!
 */
bool PowerCubeCtrl::setMaxVelocity(const std::vector<double>& maxVelocities)
{
	PCTRL_CHECK_INITIALIZED();

	for (int i = 0; i < m_params->GetDOF(); i++)
	{
		pthread_mutex_lock(&m_mutex);
		//std::cout << "------------------------------> PCube_setMaxVel()" << std::endl;
		PCube_setMaxVel(m_DeviceHandle, m_params->GetModuleID(i), maxVelocities[i]);
		pthread_mutex_unlock(&m_mutex);
		m_params->SetMaxVel(maxVelocities);
	}

	return true;
}
/*!
 * \brief Sets the maximum angular velocity (rad/s) for the Joints, use with care!
 *
 * A Value of 0.5 is already pretty fast, you probably don't want anything more than one...
 */
bool PowerCubeCtrl::setMaxVelocity(double maxVelocity)
{
	PCTRL_CHECK_INITIALIZED();
	for (int i = 0; i < m_params->GetDOF(); i++)
	{
		pthread_mutex_lock(&m_mutex);
		PCube_setMaxVel(m_DeviceHandle, m_params->GetModuleID(i), maxVelocity);
		pthread_mutex_unlock(&m_mutex);

		std::vector<double> maxVelocities(maxVelocity);
		m_params->SetMaxVel(maxVelocities);
	}

	return true;
}
/*!
 * \brief Sets the maximum angular acceleration (rad/s^2) for the Joints, use with care!
 *
 * A Value of 0.5 is already pretty fast, you probably don't want anything more than one...
 */
bool PowerCubeCtrl::setMaxAcceleration(double maxAcceleration)
{
	PCTRL_CHECK_INITIALIZED();

	for (int i = 0; i < m_params->GetDOF(); i++)
	{
		pthread_mutex_lock(&m_mutex);
		//std::cout << "------------------------------> PCube_setMaxAcc()" << std::endl;
		PCube_setMaxAcc(m_DeviceHandle, m_params->GetModuleID(i), maxAcceleration);
		pthread_mutex_unlock(&m_mutex);
		std::vector<double> maxAccelerations(maxAcceleration);
		m_params->SetMaxAcc(maxAccelerations);
	}

	return true;
}
/*!
 * \brief Returns the current states
 */
bool PowerCubeCtrl::updateStates()
{
	PCTRL_CHECK_INITIALIZED();

	unsigned int DOF = m_params->GetDOF();

	unsigned long state;
	
	unsigned long state_s; // for debug

	unsigned char dio;
	float position;
	int ret = 0;
	for (unsigned int i = 0; i < DOF; i++)
	{	
		state_s = m_status[i]; 
		pthread_mutex_lock(&m_mutex);
		ret = PCube_getStateDioPos(m_DeviceHandle, m_params->GetModuleID(i), &state, &dio, &position);
		pthread_mutex_unlock(&m_mutex);
		
		if (ret != 0)
		{
			//m_pc_status = PC_CTRL_ERR;
			std::cout << "State: Error com" << std::endl; 			
		}
		else
		{	if( state_s != state)
			{
				std::cout << "State: " << state << "Joint: " << i << std::endl; 
			}
		 	m_status[i] = state;
			m_dios[i] = dio;
			m_positions[i] = position;
		}	
		
    /// ToDo: calculate vel and acc
    ///m_velocities = ???;
    ///m_accelerations = ???
	}
	
	return true;
}
bool PowerCubeCtrl::MoveVel(const std::vector<double>& velocities)
{
	PCTRL_CHECK_INITIALIZED();

	unsigned int DOF = m_params->GetDOF();

	/// getting limits
	std::vector<double> lowerLimits = m_params->GetLowerLimits();
	std::vector<double> upperLimits = m_params->GetUpperLimits();
	std::vector<double> maxVels = m_params->GetMaxVel();
	/// check dimensions
	if (velocities.size() != DOF)
	{
		m_ErrorMessage = "Skipping command: Commanded velocities and DOF are not same dimension.";
		return false;
	}

	for (unsigned int i = 0; i < DOF; i++)
	{
	  /// check velocity limit
	  if(velocities[i] > maxVels[i])
	    {
		std::ostringstream errorMsg;
		errorMsg << "Skipping command: Velocity " << velocities[i] << " exceeds limit " << maxVels[i] << "for axis " << i;
		m_ErrorMessage = errorMsg.str();
		return false;
	
	    }
	  /// check position limits
	  double targetpos = m_positions[i] + (0.02 * velocities[i]);
	  if (targetpos < lowerLimits[i] || targetpos > upperLimits[i])
		{
			std::ostringstream errorMsg;
			errorMsg << "Skipping command: Target position " << targetpos << " exceeds limit " << lowerLimits[i] << " - " << upperLimits[i] << "for axis " << i;
			m_ErrorMessage = errorMsg.str();
			return false;
		}
	}

	std::vector<std::string> errorMessages;
	PC_CTRL_STATUS status;
	getStatus(status, errorMessages);
	if ((status != PC_CTRL_OK))
	{
		m_ErrorMessage.assign("");
		for (unsigned int i = 0; i < DOF; i++)
		{
			m_ErrorMessage.append(errorMessages[i]);
			m_ErrorMessage.append("\n");
		}
		return false;
	}

	float delta_t;
  	delta_t = ros::Time::now().toSec() - m_last_time_pub.toSec();
	m_last_time_pub = ros::Time::now();  

	/// Display Timegap with time before and after update
	//std::cout << "\n-------\nTimegap\n-------\n time now = " << ros::Time::now() << "\n last time = " << m_last_time_pub << "\n difference = " << delta_t << std::endl;
	
	for (unsigned int i = 0; i < DOF; i++)
	{
		float pos;
		float cmd_pos;
		unsigned short cmd_time; // time in milliseconds
    
    	// limit step time to 20msec
    	if (delta_t >= 0.020)
    	{
    		cmd_time = 0.020*1000; //msec
    	}
    	else
    	{
			cmd_time = delta_t * 1000; //msec
		}
		
		cmd_pos = (cmd_time/1000.0) * velocities[i];
		pthread_mutex_lock(&m_mutex);
		//std::cout << "Modul_id = " << m_params->GetModuleID(i) <<", step= "<< m_positions[i] + cmd_pos << ", time = " << cmd_time << std::endl;
		//int ret = PCube_moveVelExtended(m_DeviceHandle, m_params->GetModuleID(i), velocities[i], &m_status[i], &m_dios[i], &pos);
		int ret = PCube_moveStepExtended(m_DeviceHandle, m_params->GetModuleID(i), m_positions[i] + cmd_pos, 100*cmd_time, &m_status[i], &m_dios[i], &pos);
		pthread_mutex_unlock(&m_mutex);
		
		if (ret != 0)
		{
			m_pc_status = PC_CTRL_ERR;
		}
		m_positions[i] = (double)pos;
	}

	pthread_mutex_lock(&m_mutex);
	PCube_startMotionAll(m_DeviceHandle);
	pthread_mutex_unlock(&m_mutex);

	return true;
}
/*!
 * \brief Move joints synchronous
 *
 * Adjusting velocity of all joints to reach the final angules at the same time
 */
bool PowerCubeCtrl::MoveJointSpaceSync(const std::vector<double>& target)
{
	PCTRL_CHECK_INITIALIZED();
	unsigned int DOF = m_params->GetDOF();

	std::vector<std::string> errorMessages;
	PC_CTRL_STATUS status;
	getStatus(status, errorMessages);
	if ((status != PC_CTRL_OK))
	{
		m_ErrorMessage.assign("");
		for (unsigned int i = 0; i < DOF; i++)
		{
			m_ErrorMessage.append(errorMessages[i]);
			m_ErrorMessage.append("\n");
		}
		return false;
	}

	std::vector<double> vel(DOF);
	std::vector<double> acc(DOF);

	double TG = 0;

	try
	{
		/// calculate which joint takes the longest time to reach goal
		std::vector<double> times(DOF);
		for (unsigned int i = 0; i < DOF; i++)
		{
			RampCommand rm(m_positions[i], m_velocities[i], target[i], m_params->GetMaxAcc()[i],
						   m_params->GetMaxVel()[i]);
			times[i] = rm.getTotalTime();
		}

		/// determine the joint index that has the greatest value for time
		int furthest = 0;
		double max = times[0];
		for (unsigned int i = 1; i < DOF; i++)
		{
			if (times[i] > max)
			{
				max = times[i];
				furthest = i;
			}
		}

		RampCommand rm_furthest(m_positions[furthest], m_velocities[furthest], target[furthest],
                                m_params->GetMaxAcc()[furthest], m_params->GetMaxVel()[furthest]);

		double T1 = rm_furthest.T1();
		double T2 = rm_furthest.T2();
		double T3 = rm_furthest.T3();

		/// total time:
		TG = T1 + T2 + T3;

		/// calculate velocity and acceleration for all joints:
		acc[furthest] = m_params->GetMaxAcc()[furthest];
		vel[furthest] = m_params->GetMaxVel()[furthest];
		for (unsigned int i = 0; i < DOF; i++)
		{
			if (int(i) != furthest)
			{
				double a;
				double v;
				RampCommand::calculateAV(m_positions[i], m_velocities[i], target[i], TG, T3, m_params->GetMaxAcc()[i],
										 m_params->GetMaxVel()[i], a, v);

				acc[i] = a;
				vel[i] = v;
			}
		}
	}
	catch (...)
	{
		return false;
	}

	/// Send motion commands to hardware
	for (unsigned int i = 0; i < DOF; i++)
	{
		pthread_mutex_lock(&m_mutex);
		PCube_moveRamp(m_DeviceHandle, m_params->GetModuleIDs()[i], target[i], fabs(vel[i]), fabs(acc[i]));
		pthread_mutex_unlock(&m_mutex);
	}

	pthread_mutex_lock(&m_mutex);
	PCube_startMotionAll(m_DeviceHandle);
	pthread_mutex_unlock(&m_mutex);

	return true;
}
bool PowerCubeCtrl::MoveVel(const std::vector<double>& velocities)
{
	PCTRL_CHECK_INITIALIZED();

	unsigned int DOF = m_params->GetDOF();

	/// getting limits
	std::vector<double> lowerLimits = m_params->GetLowerLimits();
	std::vector<double> upperLimits = m_params->GetUpperLimits();
	std::vector<double> maxVels = m_params->GetMaxVel();
	/// check dimensions
	if (velocities.size() != DOF)
	{
		m_ErrorMessage = "Skipping command: Commanded velocities and DOF are not same dimension.";
		return false;
	}

	for (unsigned int i = 0; i < DOF; i++)
	{
	  /// check velocity limit
	  if(velocities[i] > maxVels[i])
	    {
	      //velocities[i] = maxVels[i];
		std::ostringstream errorMsg;
		errorMsg << "Velocity " << velocities[i] << " exceeds limit " << maxVels[i] << "for axis " << i << " moving with " << maxVels[i] << " instead";
		m_ErrorMessage = errorMsg.str();
	
	    }
	  /// check position limits
	  double targetpos = m_positions[i] + (0.02 * velocities[i]);
	  if (targetpos < lowerLimits[i] || targetpos > upperLimits[i])
		{
			std::ostringstream errorMsg;
			errorMsg << "Skipping command: Target position " << targetpos << " exceeds limit " << lowerLimits[i] << " - " << upperLimits[i] << "for axis " << i;
			m_ErrorMessage = errorMsg.str();
			return false;
		}
	}

	std::vector<std::string> errorMessages;
	PC_CTRL_STATUS status;
	getStatus(status, errorMessages);
	if ((status != PC_CTRL_OK))
	{
		m_ErrorMessage.assign("");
		for (unsigned int i = 0; i < DOF; i++)
		{
			m_ErrorMessage.append(errorMessages[i]);
		}
		return false;
	}

	float delta_t;
  	delta_t = ros::Time::now().toSec() - m_last_time_pub.toSec();
	m_last_time_pub = ros::Time::now();  

	std::vector<double> pos_temp;
	pos_temp.resize(DOF);

	for (unsigned int i = 0; i < DOF; i++)
	{
		float pos;
		float cmd_pos;
		double  cmd_time; // time in milliseconds
 
	    	// limit step time to 20msec
	    	if (delta_t >= 0.050)
		{
		  cmd_time = 0.050; //sec
	    	}
		else
		  cmd_time = delta_t; //sec
		cmd_pos = cmd_time * velocities[i];
		pthread_mutex_lock(&m_mutex);
		//std::cout << "Modul_id = " << m_params->GetModuleID(i) <<", step= "<< m_positions[i] + cmd_pos << ", time = " << cmd_time << std::endl;
		//int ret = PCube_moveVelExtended(m_DeviceHandle, m_params->GetModuleID(i), velocities[i], &m_status[i], &m_dios[i], &pos);
		int ret = PCube_moveStepExtended(m_DeviceHandle, m_params->GetModuleID(i), m_positions[i] + cmd_pos, (cmd_time+m_horizon), &m_status[i], &m_dios[i], &pos);
		pthread_mutex_unlock(&m_mutex);
		
		if (ret != 0)
		{
		  pos = m_positions[i];
		  std::cout << ret << std::endl;
		//	m_pc_status = PC_CTRL_ERR;
		}
		
		// !!! Position in pos is position before moveStep movement, to get the expected position after the movement (required as input to the next moveStep command) we add the delta position (cmd_pos) !!!
		m_positions[i] = (double)pos + cmd_pos;
		pos_temp[i] = (double)pos;
		
	}
	// Calculation of velocities based on vel = 1/(6*dt) * (-pos(t-3) - 3*pos(t-2) + 3*pos(t-1) + pos(t))
	if(m_cached_pos.size() < 4)
	  {
	    m_cached_pos.push_back(pos_temp);
	    for(unsigned int i = 0; i < DOF; i++)
	      m_velocities[i] = 0.0;
	  }
	else
	  {
	    m_cached_pos.push_back(pos_temp);
	    m_cached_pos.pop_front();
	    for(unsigned int i = 0; i < DOF; i++)
	      {
		m_velocities[i] = 1/(6*delta_t) * (-m_cached_pos[0][i]-(3*m_cached_pos[1][i])+(3*m_cached_pos[2][i])+m_cached_pos[3][i]);
	      }
	  }

	pthread_mutex_lock(&m_mutex);
	PCube_startMotionAll(m_DeviceHandle);
	pthread_mutex_unlock(&m_mutex);

	return true;
}
示例#12
0
bool PowerCubeCtrl::MoveVel(const std::vector<double>& velocities)
{
  PCTRL_CHECK_INITIALIZED();

  unsigned int DOF = m_params->GetDOF();
  std::vector<double> lowerLimits = m_params->GetLowerLimits();
  std::vector<double> upperLimits = m_params->GetUpperLimits();

  // check dimensions
  if (velocities.size() != DOF)
  {
    m_ErrorMessage = "Skipping command: Commanded velocities and DOF are not same dimension.";
    return false;
  }

  for (unsigned int i = 0; i < DOF; i++)
  {
    // check limits
    if (velocities[i] < lowerLimits[i] || velocities[i] > upperLimits[i])
    {
      std::ostringstream errorMsg;
      errorMsg << "Skipping command: Velocity " << velocities[i] << " exceeds limit " << lowerLimits[i] << " - " << upperLimits[i] << "for axis " << i;
      m_ErrorMessage = errorMsg.str();
      return false;
    }
  }

  std::vector<std::string> errorMessages;
  PC_CTRL_STATUS status;
  getStatus(status, errorMessages);
  if ((status != PC_CTRL_OK))
  {
    m_ErrorMessage.assign("");
    for (unsigned int i = 0; i < DOF; i++)
    {
      m_ErrorMessage.append(errorMessages[i]);
      m_ErrorMessage.append("\n");
    }
    return false;
  }
  //#############################################
  //############  D  E  B  U  G  ################
  //#############################################
  
  //Init
  float delta_t;
  
  //Berechne delta_t
  delta_t = ros::Time::now().toSec() - last_time_pub_.toSec(); 
  
  //Display Timegap with time before and after update
  std::cout << "\n-------\nTimegap\n-------\n time now = " << ros::Time::now() << "\n last time = " << last_time_pub_ << "\n difference = " << delta_t << std::endl;
				
  last_time_pub_ = ros::Time::now(); 
	
  for (unsigned int i = 0; i < DOF; i++) //vorher i < DOF
  {
 
    float pos;
    float cmd_pos;
    float cmd_pos_abs; // absolute position
    unsigned short cmd_time; // time in milliseconds
    
    // ToDo: Hier getHorizon() Funktion benutzen um die aktuelle Frequenz auszulesen die in arm_sdh.yaml gespeichert ist. Daraus mit 1/getHorizon() den ersten Wert ermitteln.
	if (countr == 0)
	{
		cmd_time = 17; 
		if (i == DOF-1)
			countr = countr + 1;
	}

	else
	{
		cmd_time = delta_t * 1000;
	}

    cmd_pos = (cmd_time/1000.0) * velocities[i];
	pthread_mutex_lock(&m_mutex);
    PCube_moveStepExtended(m_DeviceHandle, m_params->GetModuleID(i), m_positions[i] + cmd_pos, cmd_time, &m_status[i], &m_dios[i], &pos);
    pthread_mutex_unlock(&m_mutex);
	m_positions[i] = (double)pos;
  }

  pthread_mutex_lock(&m_mutex);
  //std::cout << "------------------------------> PCube_startMotionAll()" << std::endl;
  PCube_startMotionAll(m_DeviceHandle);
  pthread_mutex_unlock(&m_mutex);

  return true;
  
}
示例#13
0
bool PowerCubeCtrl::MoveVel(const std::vector<double>& velocities)
{
  PCTRL_CHECK_INITIALIZED();

  unsigned int DOF = m_params->GetDOF();
  std::vector<double> lowerLimits = m_params->GetLowerLimits();
  std::vector<double> upperLimits = m_params->GetUpperLimits();

  // check dimensions
  if (velocities.size() != DOF)
  {
    m_ErrorMessage = "Skipping command: Commanded velocities and DOF are not same dimension.";
    return false;
  }

  for (unsigned int i = 0; i < DOF; i++)
  {
    // check limits
    if (velocities[i] < lowerLimits[i] || velocities[i] > upperLimits[i])
    {
      m_ErrorMessage = "Skipping command: Velocity exceeds limits.";
      return false;
    }
  }

  std::vector<std::string> errorMessages;
  PC_CTRL_STATUS status;
  getStatus(status, errorMessages);
  if ((status != PC_CTRL_OK))
  {
    m_ErrorMessage.assign("");
    for (unsigned int i = 0; i < DOF; i++)
    {
      m_ErrorMessage.append(errorMessages[i]);
      m_ErrorMessage.append("\n");
    }
    return false;
  }

  for (unsigned int i = 0; i < DOF; i++)
  {
    float pos;
    float cmd_pos;
    unsigned short cmd_time; // time in milliseconds

    // calculate horizon
    cmd_time = getHorizon() * 1000; // time in milliseconds
    cmd_pos = cmd_time * velocities[i];

    pthread_mutex_lock(&m_mutex);
    //PCube_moveVelExtended(m_DeviceHandle, m_params->GetModuleID(i), velocities[i], &m_status[i], &m_dios[i], &pos);
    PCube_moveStepExtended(m_DeviceHandle, m_params->GetModuleID(i), cmd_pos, cmd_time, &m_status[i], &m_dios[i], &pos);
    m_positions[i] = (double)pos;
    pthread_mutex_unlock(&m_mutex);
  }

  pthread_mutex_lock(&m_mutex);
  PCube_startMotionAll( m_DeviceHandle);
  pthread_mutex_unlock(&m_mutex);

  return true;
}