00001
00002
00003
00004
00005
00006
00007 #include "arm/teleop_arm_dish.h"
00008 #include "arm/cartesian_move.h"
00009 #include "arm/cartesian_moves.h"
00010 #include "arm/constant_move_time.h"
00011 #include "time_server/time_srv.h"
00012 #include "arm/movement_definitions.h"
00013 #include <cmath>
00014
00015 #define MIDPOINT 4.5
00016
00020 TeleopArmDish::TeleopArmDish()
00021 {
00022 init();
00023 run();
00024 }
00025
00033 void TeleopArmDish::init()
00034 {
00035
00036 getParams();
00037
00038
00039
00040
00041
00042 cmd_pub_ = n_.advertise<arm::constant_move_time>("constant_move_times", 1);
00043 time_client_ = n_.serviceClient<time_server::time_srv>("time_service");
00044
00045
00046 ROS_INFO("Waiting for subscriber...");
00047 while (cmd_pub_.getNumSubscribers() < 1 && ros::ok());
00048
00049
00050 cat_sub_ = n_.subscribe("cats", 1000, &TeleopArmDish::callback, this);
00051 }
00052
00056 void TeleopArmDish::getParams()
00057 {
00058
00059 if (!n_.getParam("arm_speed", speed_))
00060 {
00061 ROS_WARN("Could not load arm_speed parameter, default is 2");
00062 speed_ = 2;
00063 }
00064
00065
00066 if (!n_.getParam("arm_safe_range", arm_safe_range_))
00067 {
00068 ROS_WARN("Could not load arm_safe_range parameter, default is 20000.0");
00069 arm_safe_range_ = 20000.0;
00070 }
00071
00072
00073 if (!n_.getParam("max_range_from_midpoint", max_range_from_midpoint_))
00074 {
00075 ROS_WARN("Could not load max_range_from_midpoint parameter, default is 1.0");
00076 max_range_from_midpoint_ = 1.0;
00077 }
00078 }
00079
00086 void TeleopArmDish::run()
00087 {
00088 while(ros::ok())
00089 {
00090 ros::spinOnce();
00091 if (!queue_.empty())
00092 {
00093
00094
00095 publishConstantMove();
00096 }
00097 }
00098 }
00099
00108 void TeleopArmDish::callback(const burst_calc::cat::ConstPtr& c)
00109 {
00110 queue_.push(*c);
00111 }
00112
00120 void TeleopArmDish::publishCartesianMove()
00121 {
00122 burst_calc::cat cat = queue_.front();
00123 queue_.pop();
00124 time_server::time_srv cat_start;
00125 cat_start.request.target = cat.header.stamp;
00126
00127 if (time_client_.call(cat_start))
00128 {
00129 printf("CAT start time : %f\n", cat.header.stamp.toSec());
00130 printf("Server time : %f\n", cat_start.response.actual.toSec());
00131 printf("Delta : %f\n", cat_start.response.delta.toSec());
00132
00133
00134 if (cat_start.response.delta >= ros::Duration(0))
00135 {
00136 ROS_INFO("Sleeping for %.3fs", cat_start.response.delta.toSec());
00137 (cat_start.response.delta - ros::Duration(0.1)).sleep();
00138
00139
00140 arm::cartesian_moves cmd;
00141 cmd.header.stamp = cat.header.stamp;
00142 cmd.end = cat.end;
00143 int size = cat.cas.size();
00144 for (int i = 0; i < size; i++)
00145 {
00146 arm::cartesian_move move;
00147 move.header.stamp = cat.header.stamp;
00148
00149
00150 move.speeds.fill(static_cast<int8_t>(speed_));
00151
00152
00153 move.positions[X] = getArmCoord(cat.cas[i].x);
00154 move.positions[Y] = getArmCoord(cat.cas[i].y);
00155 move.positions[Z] = ORIGIN_POSITION[Z];
00156 move.positions[YAW] = ORIGIN_POSITION[YAW];
00157 move.positions[PITCH] = ORIGIN_POSITION[PITCH];
00158 move.positions[ROLL] = ORIGIN_POSITION[ROLL];
00159 move.positions[GRIP] = ORIGIN_POSITION[GRIP];
00160
00161
00162
00163
00164
00165 if (fabs(move.positions[X] > 20000))
00166 {
00167 ROS_ERROR("X-axis position (%f) out of bounds", move.positions[X]);
00168 move.positions[X] = 0;
00169 }
00170 if (fabs(move.positions[Y] > 20000))
00171 {
00172 ROS_ERROR("Y-axis position (%f) out of bounds", move.positions[Y]);
00173 move.positions[Y] = 0;
00174 }
00175
00176 cmd.moves.push_back(move);
00177 }
00178
00179
00180 cmd_pub_.publish(cmd);
00181 ROS_INFO("Command published, sleeping for %.3fs",
00182 (cat.end - cat.header.stamp).toSec());
00183 (cat.end - cat.header.stamp).sleep();
00184
00185 time_server::time_srv cat_end;
00186 cat_end.request.target = cat.end;
00187 time_client_.call(cat_end);
00188 printf("CAT end time : %f\n", cat.end.toSec());
00189 printf("Server time : %f\n", cat_end.response.actual.toSec());
00190 printf("Delta : %f\n", cat_end.response.delta.toSec());
00191 }
00192 else
00193 ROS_ERROR("CAT start time is behind server time, no command will be issued");
00194 }
00195 else
00196 ROS_ERROR("Time server is not responding, no command will be issued");
00197 }
00198
00206 void TeleopArmDish::publishConstantMove()
00207 {
00208 burst_calc::cat cat = queue_.front();
00209 queue_.pop();
00210 time_server::time_srv cat_start;
00211 cat_start.request.target = cat.header.stamp;
00212
00213 if (time_client_.call(cat_start))
00214 {
00215
00216
00217
00218
00219
00220 if (cat_start.response.delta >= ros::Duration(0))
00221 {
00222 ROS_INFO("SLeeping for %.3fs before publishing command",
00223 cat_start.response.delta.toSec());
00224 cat_start.response.delta.sleep();
00225
00226 arm::constant_move_time cmd;
00227 cmd.header.stamp = cat.header.stamp;
00228 cmd.end = cat.end;
00229 int size = cat.cas.size();
00230 double x = 0.0;
00231 double y = 0.0;
00232
00233
00234 for (int i = 0; i < size; i++)
00235 {
00236 x += cat.cas[i].x;
00237 y += cat.cas[i].y;
00238 }
00239
00240
00241 x /= size;
00242 y /= size;
00243 printf("X: %.3f Y: %.3f\n", x, y);
00244
00245
00246
00247
00248 if (y - MIDPOINT < 0)
00249 {
00250 ROS_INFO("Y is ABOVE the midpoint, moving FORWARD");
00251 cmd.move.states[X] = ARM_FORWARD;
00252 }
00253 else
00254 {
00255 ROS_INFO("Y is BELOW the midpoint, moving BACKWARD");
00256 cmd.move.states[X] = ARM_BACKWARD;
00257 }
00258
00259 if (x - MIDPOINT < 0)
00260 {
00261 ROS_INFO("X is to the LEFT of the midpoint, moving LEFT");
00262 cmd.move.states[Y] = ARM_LEFT;
00263 }
00264 else
00265 {
00266 ROS_INFO("X is to the RIGHT of the midpoint, moving RIGHT");
00267 cmd.move.states[Y] = ARM_RIGHT;
00268 }
00269
00270
00271
00272 cmd.move.speeds.fill(static_cast<int8_t>(speed_));
00273
00274
00275 cmd.move.states[Z] = 0;
00276 cmd.move.states[YAW] = 0;
00277 cmd.move.states[PITCH] = 0;
00278 cmd.move.states[ROLL] = 0;
00279 cmd.move.states[GRIP] = 0;
00280 cmd.move.states[LIFT] = 0;
00281
00282 printf("[%d] [%d] [%d] [%d] [%d] [%d] [%d] [%d]\n",
00283 cmd.move.states[X], cmd.move.states[Y],
00284 cmd.move.states[Z], cmd.move.states[YAW],
00285 cmd.move.states[PITCH], cmd.move.states[ROLL],
00286 cmd.move.states[GRIP], cmd.move.states[LIFT]);
00287 printf("[%d] [%d] [%d] [%d] [%d] [%d] [%d]\n",
00288 cmd.move.speeds[X], cmd.move.speeds[Y],
00289 cmd.move.speeds[Z], cmd.move.speeds[YAW],
00290 cmd.move.speeds[PITCH], cmd.move.speeds[ROLL],
00291 cmd.move.speeds[GRIP]);
00292
00293
00294 cmd_pub_.publish(cmd);
00295 ROS_INFO("Sleeping for duration of command (%.3fs)",
00296 (cat.end - cat.header.stamp).toSec());
00297 (cat.end - cat.header.stamp).sleep();
00298
00299
00300
00301
00302
00303
00304
00305 }
00306 else
00307 {
00308 ROS_ERROR("CAT start time (%.3f) is behind server time (%.3f): no command will be issued",
00309 cat_start.request.target.toSec(), cat_start.response.actual.toSec());
00310 }
00311 }
00312 else
00313 ROS_ERROR("Time server is not responding: no command will be issued");
00314 }
00315
00325 double TeleopArmDish::getArmCoord(double coord)
00326 {
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341 return (coord - MIDPOINT) * -(arm_safe_range_ / max_range_from_midpoint_);
00342 }
00343
00347 int main(int argc, char** argv)
00348 {
00349 ros::init(argc, argv, "teleop_arm_dish");
00350 TeleopArmDish teleop_arm_dish;
00351 return 0;
00352 }