-
Notifications
You must be signed in to change notification settings - Fork 196
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
merge branch boneil_point_streaming manually #88
base: indigo-devel
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -159,6 +159,73 @@ void JointTrajectoryStreamer::jointTrajectoryCB(const trajectory_msgs::JointTraj | |
send_to_robot(new_traj_msgs); | ||
} | ||
|
||
void JointTrajectoryStreamer::jointCommandCB(const trajectory_msgs::JointTrajectoryConstPtr &msg) | ||
{ | ||
// read current state value (should be atomic) | ||
int state = this->state_; | ||
|
||
ROS_DEBUG("Current state is: %d", state); | ||
|
||
//If current state is idle, set to POINT_STREAMING | ||
if (TransferStates::IDLE == state) | ||
{ | ||
this->mutex_.lock(); | ||
this->state_ = TransferStates::POINT_STREAMING; | ||
this->current_point_ = 0; | ||
this->streaming_sequence = 0; | ||
this->streaming_start_ = ros::Time::now(); | ||
this->mutex_.unlock(); | ||
state = TransferStates::POINT_STREAMING; | ||
ROS_INFO("First joint point received. Starting on-the-fly streaming."); | ||
} | ||
|
||
//if current state is POINT_STREAMING, process incoming point. | ||
if (TransferStates::POINT_STREAMING == state) | ||
{ | ||
if (msg->points.empty()) | ||
{ | ||
ROS_INFO("Empty point received, cancelling current trajectory"); | ||
return; | ||
} | ||
|
||
//Else, Push point into queue | ||
SimpleMessage message; | ||
trajectory_msgs::JointTrajectoryPoint rbt_pt, xform_pt; | ||
|
||
// select / reorder joints for sending to robot | ||
if (!select(msg->joint_names, msg->points[0], this->all_joint_names_, &rbt_pt)) | ||
return; | ||
|
||
// transform point data (e.g. for joint-coupling) | ||
if (!transform(rbt_pt, &xform_pt)) | ||
return; | ||
|
||
// convert trajectory point to ROS message | ||
if (!create_message(this->streaming_sequence, xform_pt, &message)) | ||
return; | ||
|
||
//Points get pushed into queue here. They will be popped in the Streaming Thread and sent to controller. | ||
this->mutex_.lock(); | ||
this->streaming_queue_.push(message); | ||
this->streaming_sequence++; | ||
this->mutex_.unlock(); | ||
} | ||
|
||
//Else, cannot splice. Cancel current motion. | ||
else | ||
{ | ||
if (msg->points.empty()) | ||
ROS_INFO("Empty trajectory received, canceling current trajectory"); | ||
else | ||
ROS_ERROR("Trajectory splicing not yet implemented, stopping current motion."); | ||
|
||
this->mutex_.lock(); | ||
trajectoryStop(); | ||
this->mutex_.unlock(); | ||
return; | ||
} | ||
} | ||
|
||
bool JointTrajectoryStreamer::send_to_robot(const std::vector<SimpleMessage>& messages) | ||
{ | ||
ROS_INFO("Loading trajectory, setting state to streaming"); | ||
|
@@ -276,8 +343,43 @@ void JointTrajectoryStreamer::streamingThread() | |
ROS_WARN("Failed sent joint point, will try again"); | ||
|
||
break; | ||
|
||
case TransferStates::POINT_STREAMING: | ||
ROS_INFO("I'm streaming, sir."); | ||
// if no points in queue, streaming complete, set to idle. | ||
if (this->streaming_queue_.empty()) | ||
{ | ||
ROS_INFO("Point streaming complete, setting state to IDLE"); | ||
this->state_ = TransferStates::IDLE; | ||
break; | ||
} | ||
// if not connected, reconnect. | ||
if (!this->connection_->isConnected()) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this reconnection logic required? Why doesn't this logic handle it? |
||
{ | ||
ROS_DEBUG("Robot disconnected. Attempting reconnect..."); | ||
connectRetryCount = 5; | ||
break; | ||
} | ||
// otherwise, send point to robot. | ||
tmpMsg = this->streaming_queue_.front(); | ||
this->streaming_queue_.pop(); | ||
msg.init(tmpMsg.getMessageType(), CommTypes::SERVICE_REQUEST, | ||
ReplyTypes::INVALID, tmpMsg.getData()); // set commType=REQUEST | ||
|
||
ROS_DEBUG("Sending joint trajectory point"); | ||
if (this->connection_->sendAndReceiveMsg(msg, reply, false)) | ||
{ | ||
ROS_INFO("Point[%d] sent to controller", this->current_point_); | ||
this->current_point_++; | ||
} | ||
else | ||
ROS_WARN("Failed sent joint point, will try again"); | ||
|
||
break; | ||
// consider checking for controller point starvation here. use a timer to check if the state is popping in and out of POINT_STREAMING mode, indicating something is trying to send streaming points, but is doing so too slowly. It may, in fact, not matter other than motion won't be smooth. | ||
|
||
default: | ||
ROS_ERROR("Joint trajectory streamer: unknown state"); | ||
ROS_ERROR("Joint trajectory streamer: unknown state, %d", this->state_); | ||
this->state_ = TransferStates::IDLE; | ||
break; | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -295,7 +295,7 @@ bool MotomanJointTrajectoryStreamer::VectorToJointData(const std::vector<double> | |
JointData &joints) | ||
{ | ||
if (vec.size() > joints.getMaxNumJoints()) | ||
ROS_ERROR_RETURN(false, "Failed to copy to JointData. Len (%d) out of range (0 to %d)", | ||
ROS_ERROR_RETURN(false, "Failed to copy to JointData. Len (%ld) out of range (0 to %d)", | ||
vec.size(), joints.getMaxNumJoints()); | ||
|
||
joints.init(); | ||
|
@@ -401,6 +401,74 @@ void MotomanJointTrajectoryStreamer::streamingThread() | |
} | ||
} | ||
break; | ||
|
||
case TransferStates::POINT_STREAMING: | ||
// if no points in queue, streaming complete, set to idle. | ||
if (this->streaming_queue_.empty()) | ||
{ | ||
if (this->time_since_last < this->point_streaming_timeout) | ||
{ | ||
time_since_last = ros::Time::now().toSec() - time_of_last; | ||
ros::Duration(0.005).sleep(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you make the |
||
//ROS_INFO("Time since last point: %f", time_since_last); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can this log message be deleted? Or should it be of type DEBUG? |
||
break; | ||
} | ||
else | ||
{ | ||
ROS_INFO("Point streaming complete, setting state to IDLE"); | ||
this->state_ = TransferStates::IDLE; | ||
break; | ||
} | ||
} | ||
// if not connected, reconnect. | ||
if (!this->connection_->isConnected()) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do you know why this reconnect logic is needed here? Why doesn't the reconnect here work? |
||
{ | ||
ROS_DEBUG("Robot disconnected. Attempting reconnect..."); | ||
connectRetryCount = 5; | ||
break; | ||
} | ||
// otherwise, send point to robot. | ||
tmpMsg = this->streaming_queue_.front(); | ||
msg.init(tmpMsg.getMessageType(), CommTypes::SERVICE_REQUEST, | ||
ReplyTypes::INVALID, tmpMsg.getData()); // set commType=REQUEST | ||
|
||
ROS_INFO("Sending joint trajectory point"); | ||
if (this->connection_->sendAndReceiveMsg(msg, reply, false)) | ||
{ | ||
MotionReplyMessage reply_status; | ||
if (!reply_status.init(reply)) | ||
{ | ||
ROS_ERROR("Aborting point stream operation."); | ||
this->state_ = TransferStates::IDLE; | ||
break; | ||
} | ||
if (reply_status.reply_.getResult() == MotionReplyResults::SUCCESS) | ||
{ | ||
ROS_INFO("Point[%d] sent to controller", this->current_point_); | ||
this->current_point_++; | ||
time_since_last = 0.0; | ||
time_of_last = ros::Time::now().toSec(); | ||
this->streaming_queue_.pop(); | ||
} | ||
else if (reply_status.reply_.getResult() == MotionReplyResults::BUSY) | ||
{ | ||
ROS_INFO("silently resending."); | ||
break; // silently retry sending this point | ||
} | ||
else | ||
{ | ||
ROS_ERROR_STREAM("Aborting point stream operation. Failed to send point" | ||
<< " (#" << this->current_point_ << "): " | ||
<< MotomanMotionCtrl::getErrorString(reply_status.reply_)); | ||
this->state_ = TransferStates::IDLE; | ||
break; | ||
} | ||
} | ||
else | ||
ROS_WARN("Failed sent joint point, will try again"); | ||
|
||
break; | ||
|
||
default: | ||
ROS_ERROR("Joint trajectory streamer: unknown state"); | ||
this->state_ = TransferStates::IDLE; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can this be deleted?