$search
00001 /* 00002 * Software License Agreement (BSD License) 00003 * 00004 * Copyright (c) 2011, Yaskawa America, Inc. 00005 * All rights reserved. 00006 * 00007 * Redistribution and use in source and binary forms, with or without 00008 * modification, are permitted provided that the following conditions are met: 00009 * 00010 * * Redistributions of source code must retain the above copyright 00011 * notice, this list of conditions and the following disclaimer. 00012 * * Redistributions in binary form must reproduce the above copyright 00013 * notice, this list of conditions and the following disclaimer in the 00014 * documentation and/or other materials provided with the distribution. 00015 * * Neither the name of the Yaskawa America, Inc., nor the names 00016 * of its contributors may be used to endorse or promote products derived 00017 * from this software without specific prior written permission. 00018 * 00019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00020 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00021 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00022 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 00023 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00024 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00025 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00026 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00027 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00028 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00029 * POSSIBILITY OF SUCH DAMAGE. 00030 */ 00031 00032 #include "p_var_q.h" 00033 00034 using std::cout; 00035 using std::cin; 00036 using std::endl; 00037 using std::ofstream; 00038 00039 PVarQ::PVarQ(MotoSocket *sock, ofstream* log_file) 00040 // Constructor for position variable queue object 00041 // Adds initialization message to queue and stores socket 00042 { 00043 this->sock = sock; 00044 ack_received = true; 00045 num_traj_recv = 0; 00046 num_traj_send = 0; 00047 this->log_file = log_file; 00048 } 00049 00050 PVarQ::~PVarQ(void) 00051 // Destruct for position variable queue object 00052 { 00053 } 00054 00055 void PVarQ::addTraj(const trajectory_msgs::JointTrajectory& traj) 00056 // Adds received trajectory to messages queue, taking care to add necessary commands 00057 { 00058 cout << "traj received" << endl; 00059 const int NUMPOINTS = traj.points.size(); 00060 message pvq_message; 00061 00062 if (messages.empty()) 00063 addMessage(CMD_INIT_PVQ); 00064 else if (messages.back().contents[0] == CMD_END_PVQ) 00065 addMessage(CMD_INIT_PVQ); 00066 00067 memset(pvq_message.contents, UNUSED, sizeof(pvq_message.contents)); 00068 pvq_message.contents[0] = CMD_ADD_POINT_PVQ; 00069 00070 for (int i = 0; i < NUMPOINTS; i++) 00071 { 00072 for (int j = 0; j < 8; j++) 00073 { 00074 pvq_message.contents[j+2] = traj.points[i].positions[j]; 00075 } 00076 pvq_message.contents[10] = traj.points[i].velocities[0]; 00077 messages.push(pvq_message); 00078 } 00079 00080 if (NUMPOINTS >= QSIZE) // Send trajectory if it has enough points for the robot to move 00081 { 00082 /* 00083 Comment out the following line before if you don't want to end the trajectory QSIZE points early, and you'd rather 00084 send the CMD_END_PVQ command manually. If you don't send it before the robot runs out of new points, though, it 00085 will oscillate in the job along the most recent Position Variables in the loop. 00086 */ 00087 addMessage(CMD_END_PVQ); // Add on PVQ end message 00088 num_traj_recv++; 00089 //sendTraj(); // Uncomment if using motion_interface instead of interface 00090 } 00091 } 00092 00093 void PVarQ::sendTraj() 00094 // Talks to motoros_server in MotoPlus via UDP. Initiates PVQ motion, sends trajectory, stops motion. Blocks during motion. 00095 { 00096 message send_message; 00097 message recv_message; 00098 int bytes_send, bytes_recv; 00099 00100 while (!messages.empty()) 00101 { 00102 send_message = messages.front(); 00103 for (short i = 0; i < 11; i++) 00104 { 00105 cout << send_message.contents[i] << " "; 00106 } 00107 cout << endl; 00108 bytes_send = sock->sendMessage(send_message.contents, true); 00109 if (bytes_send == -1) 00110 break; 00111 bytes_recv = sock->recvMessage(recv_message.contents, true); 00112 if (bytes_recv == -1) 00113 break; 00114 for (short i = 0; i < 11; i++) 00115 { 00116 cout << recv_message.contents[i] << " "; 00117 } 00118 cout << endl; 00119 messages.pop(); 00120 } 00121 addMessage(CMD_INIT_PVQ); 00122 } 00123 00124 void PVarQ::addMessage(int command) 00125 // Adds message to messages queue 00126 { 00127 message new_message; 00128 memset(new_message.contents, UNUSED, sizeof(new_message.contents)); 00129 new_message.contents[0] = command; 00130 messages.push(new_message); 00131 } 00132 00133 int PVarQ::sendMessage() 00134 // Performs non-blocking send on next message in queue. If successful, logs message and sets "ack_received" flag to "false." 00135 { 00136 int bytes_send = sock->sendMessage(messages.front().contents, false); 00137 if (bytes_send > 0) 00138 { 00139 ack_received = false; 00140 logMessage(messages.front(), true); 00141 messages.pop(); 00142 } 00143 return bytes_send; 00144 } 00145 00146 int PVarQ::recvMessage() 00147 // Receives (non-blocking) message from robot. If successful, logs message and sets "ack_received" flag to "true." 00148 { 00149 message recv_message; 00150 memset(recv_message.contents, 0, 44); 00151 int bytes_recv = sock->recvMessage(recv_message.contents, false); 00152 if (bytes_recv > 0) 00153 { 00154 ack_received = true; 00155 logMessage(recv_message, false); 00156 if (recv_message.contents[0] == CMD_END_PVQ) 00157 num_traj_send++; 00158 } 00159 return bytes_recv; 00160 } 00161 00162 void PVarQ::logMessage(message log_message, bool is_send) 00163 // Logs and displays message 00164 { 00165 if (is_send) 00166 { 00167 cout << "sent: "; 00168 *log_file << "sent: "; 00169 } 00170 else 00171 { 00172 cout << "recv: "; 00173 *log_file << "recv: "; 00174 } 00175 for (short i = 0; i < 11; i++) 00176 { 00177 cout << log_message.contents[i] << " "; 00178 *log_file << log_message.contents[i] << " "; 00179 } 00180 cout << endl; 00181 *log_file << endl; 00182 } 00183 00184 void PVarQ::run() 00185 // Enables single non-blocking send or receive depending on communication status and if there are trajectory points left to process 00186 { 00187 if (num_traj_recv > num_traj_send) // Trajectory points remaining to proceses 00188 { 00189 if (ack_received) // Ack has been received, so send 00190 sendMessage(); 00191 if (!ack_received) // Waiting for ack, so receive 00192 recvMessage(); 00193 } 00194 }