41 std::string config_file_path;
44 bool has_path = pn.
getParam(
"config_file_path", config_file_path);
46 ROS_ERROR(
"Required parameter config_file_path could not be found on param server!");
50 pn.
param(
"use_serial", use_serial,
false);
58 pn.
param<std::string> (
"ip", ip,
"192.168.1.1");
59 pn.
param(
"port", tcpip_port, 5566);
64 pn.
param(
"serial_port", serial_port, 0);
65 if (serial_port < 0 || serial_port > 9)
67 ROS_ERROR(
"serial_port must be in the range [0-9]!");
76 ROS_INFO(
"trying to connect to katana (serial port: /dev/ttyS%d) ...", serial_port);
79 serial_config.
port = serial_port;
80 serial_config.
baud = 57600;
81 serial_config.
data = 8;
82 serial_config.
parity =
'N';
83 serial_config.
stop = 1;
84 serial_config.
rttc = 300;
85 serial_config.
wttc = 0;
88 ROS_INFO(
"success: serial connection to Katana opened");
92 ROS_INFO(
"trying to connect to katana (TCP/IP) on %s:%d...", ip.c_str(), tcpip_port);
93 char* nonconst_ip = strdup(ip.c_str());
96 ROS_INFO(
"success: TCP/IP connection to Katana opened");
101 ROS_INFO(
"success: protocol class instantiated");
104 ROS_INFO(
"success: communication with Katana initialized");
109 ROS_INFO(
"success: katana initialized");
121 ROS_INFO(
"success: katana calibrated");
137 assert(
kni.use_count() == 1);
159 boost::recursive_mutex::scoped_lock lock(
kni_mutex);
162 kni->GetBase()->recvMPS();
201 ROS_ERROR(
"WrongCRCException: Two threads tried to access the KNI at once. This means that the locking in the Katana node is broken. (exception in refreshEncoders(): %s)", e.
message().c_str());
205 ROS_ERROR(
"ReadNotCompleteException: Another program accessed the KNI. Please stop it and restart the Katana node. (exception in refreshEncoders(): %s)", e.
message().c_str());
209 ROS_ERROR(
"ParameterReadingException: Could not receive PVP (Position Velocity PWM) parameters from a motor (exception in refreshEncoders(): %s)", e.
message().c_str());
216 ROS_ERROR(
"FirmwareException: Did the arm collide with something (red LED)? (exception in refreshEncoders(): %s)", e.
message().c_str());
220 ROS_ERROR(
"Unhandled exception in refreshEncoders(): %s", e.
message().c_str());
224 ROS_ERROR(
"Unhandled exception in refreshEncoders()");
232 boost::recursive_mutex::scoped_lock lock(
kni_mutex);
235 kni->GetBase()->recvGMS();
265 ROS_ERROR(
"WrongCRCException: Two threads tried to access the KNI at once. This means that the locking in the Katana node is broken. (exception in refreshMotorStatus(): %s)", e.
message().c_str());
269 ROS_ERROR(
"ReadNotCompleteException: Another program accessed the KNI. Please stop it and restart the Katana node. (exception in refreshMotorStatus(): %s)", e.
message().c_str());
273 ROS_ERROR(
"Unhandled exception in refreshMotorStatus(): %s", e.
message().c_str());
277 ROS_ERROR(
"Unhandled exception in refreshMotorStatus()");
288 assert(traj->size() > 0);
297 ROS_DEBUG(
"Motor status: %d, %d, %d, %d, %d, %d",
motor_status_[0],
motor_status_[1],
motor_status_[2],
motor_status_[3],
motor_status_[4],
motor_status_[5]);
305 ROS_WARN(
"Motors are crashed before executing trajectory! Unblocking...");
307 boost::recursive_mutex::scoped_lock lock(
kni_mutex);
335 double time_until_start = (start_time -
ros::Time::now()).toSec();
337 if (fabs(traj->at(0).start_time) > 0.01 && time_until_start < -0.01)
342 else if (time_until_start > 0.0)
344 ROS_DEBUG(
"Sleeping %f seconds until scheduled start of trajectory", time_until_start);
349 boost::recursive_mutex::scoped_lock lock(
kni_mutex);
355 for (
size_t i = 0; i < traj->size(); i++)
357 traj->at(i).start_time += delay;
360 for (
size_t i = 0; i < traj->size(); i++)
369 int activityflag = 0;
370 if (i == (traj->size() - 1))
375 else if (seg.
start_time - traj->at(0).start_time < 0.4)
386 std::vector<short> polynomial;
391 for (
size_t j = 0; j < seg.
splines.size(); j++)
394 polynomial.push_back(s_time);
409 polynomial.push_back(s_time);
412 polynomial.push_back(0);
413 polynomial.push_back(0);
414 polynomial.push_back(0);
416 ROS_DEBUG(
"setAndStartPolyMovement(%d): ", activityflag);
418 for (
size_t k = 5; k < polynomial.size(); k += 6)
420 ROS_DEBUG(
" time: %d target: %d p0: %d p1: %d p2: %d p3: %d",
421 polynomial[k-5], polynomial[k-4], polynomial[k-3], polynomial[k-2], polynomial[k-1], polynomial[k]);
424 kni->setAndStartPolyMovement(polynomial,
false, activityflag);
430 ROS_ERROR(
"WrongCRCException: Two threads tried to access the KNI at once. This means that the locking in the Katana node is broken. (exception in executeTrajectory(): %s)", e.
message().c_str());
434 ROS_ERROR(
"ReadNotCompleteException: Another program accessed the KNI. Please stop it and restart the Katana node. (exception in executeTrajectory(): %s)", e.
message().c_str());
441 ROS_ERROR(
"FirmwareException: Motor collision? Perhaps we tried to send a trajectory that the arm couldn't follow. (exception in executeTrajectory(): %s)", e.
message().c_str());
445 ROS_ERROR(
"Unhandled exception in executeTrajectory(): %s", e.
message().c_str());
449 ROS_ERROR(
"Unhandled exception in executeTrajectory()");
456 boost::recursive_mutex::scoped_lock lock(
kni_mutex);
457 kni->flushMoveBuffers();
471 boost::recursive_mutex::scoped_lock lock(
kni_mutex);
477 ROS_ERROR(
"WrongCRCException: Two threads tried to access the KNI at once. This means that the locking in the Katana node is broken. (exception in moveJoint(): %s)", e.
message().c_str());
481 ROS_ERROR(
"ReadNotCompleteException: Another program accessed the KNI. Please stop it and restart the Katana node. (exception in moveJoint(): %s)", e.
message().c_str());
489 ROS_ERROR(
"Unhandled exception in moveJoint()");
535 return (
short)(x + 0.5);
537 return (
short)(x - 0.5);
550 kni->enableCrashLimits();
554 kni->moveMotorByEnc(1, encoders);
555 ROS_INFO(
"no calibration required");
559 ROS_INFO(
"first calibration collision... ");
562 kni->moveMotorByEnc(1, -encoders);
563 ROS_INFO(
"no calibration required");
567 ROS_INFO(
"second calibration collision: calibration required");
574 kni->disableCrashLimits();
576 kni->enableCrashLimits();
586 ROS_WARN(
"Switching all motors off!");
587 boost::recursive_mutex::scoped_lock lock(
kni_mutex);
588 kni->switchRobotOff();
594 ROS_INFO(
"Switching all motors back on.");
595 boost::recursive_mutex::scoped_lock lock(
kni_mutex);
596 kni->switchRobotOn();
613 pos1_angles[0] = 2.88;
614 pos2_angles[0] = -3.02;
616 pos1_angles[1] = 0.15;
617 pos2_angles[1] = 2.16;
619 pos1_angles[2] = 1.40;
620 pos2_angles[2] = -2.21;
622 pos1_angles[3] = 0.50;
623 pos2_angles[3] = -2.02;
625 pos1_angles[4] = 2.86;
626 pos2_angles[4] = -2.98;
628 pos1_angles[5] = -0.44;
629 pos2_angles[5] = 0.30;
636 int accel =
kni->getMotorAccelerationLimit(i);
637 int max_vel =
kni->getMotorVelocityLimit(i);
640 ROS_INFO(
"KNI encoders: %d, %d",
kni->GetBase()->GetMOT()->arr[i].GetEncoderMinPos(),
kni->GetBase()->GetMOT()->arr[i].GetEncoderMaxPos());
641 ROS_INFO(
"moving to encoders: %d, %d", pos1_encoders, pos2_encoders);
642 ROS_INFO(
"current encoders: %d",
kni->getMotorEncoders(i,
true));
644 ROS_INFO(
"Moving to min");
646 boost::recursive_mutex::scoped_lock lock(
kni_mutex);
647 kni->moveMotorToEnc(i, pos1_encoders);
656 ROS_INFO(
"Moving to max");
658 boost::recursive_mutex::scoped_lock lock(
kni_mutex);
659 kni->moveMotorToEnc(i, pos2_encoders);
virtual bool executeTrajectory(boost::shared_ptr< SpecifiedTrajectory > traj, boost::function< bool()> isPreemptRequested)
ros::ServiceServer switch_motors_off_srv_
double vel_enc2rad(int index, short encoders)
virtual void freezeRobot()
static const double KNI_TO_ROS_TIME
KNI time is in 10 milliseconds (most of the time), ROS time is in seconds.
boost::recursive_mutex kni_mutex
virtual void refreshMotorStatus()
double acc_rad2enc(int index, double acc)
std::string message() const
ros::ServiceServer switch_motors_on_srv_
virtual void setLimits(void)
ros::Time last_encoder_update_
std::vector< TMotStsFlg > motor_status_
static bool sleepUntil(const Time &end)
std::vector< double > motor_angles_
const size_t NUM_MOTORS
The number of motors in the katana (= all 5 "real" joints + the gripper)
static const int KNI_MAX_ACCELERATION
acceleration limit = 1 or 2 [enc / (10 ms)^2]
virtual bool init(CCdlBase *_device, byte _kataddr=24)
bool switchMotorsOn(std_srvs::Empty::Request &request, std_srvs::Empty::Response &response)
ServiceServer advertiseService(const std::string &service, bool(T::*srv_func)(MReq &, MRes &), T *obj)
std::vector< double > motor_velocities_
std::vector< std::string > joint_names_
ros::ServiceServer test_speed_srv_
std::vector< moveit_msgs::JointLimits > motor_limits_
double angle_rad2enc(int index, double angle)
bool param(const std::string ¶m_name, T ¶m_val, const T &default_val) const
static const int KNI_MAX_VELOCITY
velocity limit <= 180 [enc / 10 ms]
double angle_enc2rad(int index, int encoders)
bool switchMotorsOff(std_srvs::Empty::Request &request, std_srvs::Empty::Response &response)
boost::shared_ptr< CLMBase > kni
virtual bool moveJoint(int jointIndex, double turningAngle)
double vel_rad2enc(int index, double vel)
bool getParam(const std::string &key, std::string &s) const
virtual bool allMotorsReady()
virtual bool allJointsReady()
const size_t NUM_JOINTS
The number of joints in the katana (= only the 5 "real" joints)
virtual bool someMotorCrashed()
std::vector< Spline > splines
double acc_enc2rad(int index, short encoders)
bool testSpeedSrv(std_srvs::Empty::Request &request, std_srvs::Empty::Response &response)
short round(const double x)
std::vector< int > encoders
double jerk_rad2enc(int index, double jerk)