00001
00023 #include "app2/app2.h"
00024
00025 #define BARRIER_VSTIG 1
00026 #define ROBOT_SUM 20
00027
00028 #define RED_SWARM 1
00029 #define BLUE_SWARM 2
00030
00031
00032 PLUGINLIB_EXPORT_CLASS(app2::App2, micros_swarm::Application)
00033
00034 namespace app2{
00035
00036 struct XY
00037 {
00038 float x;
00039 float y;
00040 };
00041
00042 App2::App2() {}
00043
00044 App2::~App2() {}
00045
00046 void App2::stop() {}
00047
00048 void App2::init()
00049 {
00050
00051 delta_kin = 5;
00052 epsilon_kin = 100;
00053
00054 delta_nonkin = 25;
00055 epsilon_nonkin = 1000;
00056 }
00057
00058 float App2::force_mag_kin(float dist)
00059 {
00060 return -(epsilon_kin/(dist+0.1)) *(pow(delta_kin/(dist+0.1), 4) - pow(delta_kin/(dist+0.1), 2));
00061 }
00062
00063 float App2::force_mag_nonkin(float dist)
00064 {
00065 return -(epsilon_nonkin/(dist+0.1)) *(pow(delta_nonkin/(dist+0.1), 4) - pow(delta_nonkin/(dist+0.1), 2));
00066 }
00067
00068 XY App2::force_sum_kin(micros_swarm::NeighborBase n, XY &s)
00069 {
00070 micros_swarm::Base l = get_base();
00071 float xl = l.x;
00072 float yl = l.y;
00073
00074 float xn = n.x;
00075 float yn = n.y;
00076
00077 float dist = sqrt(pow((xl-xn),2)+pow((yl-yn),2));
00078
00079 float fm = force_mag_kin(dist)/1000;
00080 if(fm>0.5) {
00081 fm=0.5;
00082 }
00083
00084 float fx = (fm/(dist+0.1))*(xn-xl);
00085 float fy = (fm/(dist+0.1))*(yn-yl);
00086
00087 s.x += fx;
00088 s.y += fy;
00089 return s;
00090 }
00091
00092 XY App2::force_sum_nonkin(micros_swarm::NeighborBase n, XY &s)
00093 {
00094 micros_swarm::Base l = get_base();
00095 float xl = l.x;
00096 float yl = l.y;
00097
00098 float xn = n.x;
00099 float yn = n.y;
00100
00101 float dist = sqrt(pow((xl-xn),2)+pow((yl-yn),2));
00102
00103 float fm = force_mag_nonkin(dist)/1000;
00104 if(fm>0.5) {
00105 fm=0.5;
00106 }
00107
00108 float fx = (fm/(dist+0.1))*(xn-xl);
00109 float fy = (fm/(dist+0.1))*(yn-yl);
00110
00111 s.x += fx;
00112 s.y += fy;
00113 return s;
00114 }
00115
00116 XY App2::direction_red()
00117 {
00118 XY sum;
00119 sum.x = 0;
00120 sum.y = 0;
00121
00122 micros_swarm::Neighbors<micros_swarm::NeighborBase> n(true);
00123 boost::function<XY(micros_swarm::NeighborBase, XY &)> bf_kin = boost::bind(&App2::force_sum_kin, this, _1, _2);
00124 boost::function<XY(micros_swarm::NeighborBase, XY &)> bf_nonkin = boost::bind(&App2::force_sum_nonkin, this, _1, _2);
00125 sum = n.kin(RED_SWARM).reduce(bf_kin, sum);
00126 sum = n.nonkin(RED_SWARM).reduce(bf_nonkin, sum);
00127
00128 return sum;
00129 }
00130
00131 XY App2::direction_blue()
00132 {
00133 XY sum;
00134 sum.x = 0;
00135 sum.y = 0;
00136
00137 micros_swarm::Neighbors<micros_swarm::NeighborBase> n(true);
00138 boost::function<XY(micros_swarm::NeighborBase, XY &)> bf_kin = boost::bind(&App2::force_sum_kin, this, _1, _2);
00139 boost::function<XY(micros_swarm::NeighborBase, XY &)> bf_nonkin = boost::bind(&App2::force_sum_nonkin, this, _1, _2);
00140 sum = n.kin(BLUE_SWARM).reduce(bf_kin, sum);
00141 sum = n.nonkin(BLUE_SWARM).reduce(bf_nonkin, sum);
00142
00143 return sum;
00144 }
00145
00146 bool App2::red(int id)
00147 {
00148 if(id <= 9) {
00149 return true;
00150 }
00151 return false;
00152 }
00153
00154 bool App2::blue(int id)
00155 {
00156 if(id >= 10) {
00157 return true;
00158 }
00159 return false;
00160 }
00161
00162 void App2::publish_red_cmd(const ros::TimerEvent&)
00163 {
00164 XY v = direction_red();
00165 geometry_msgs::Twist t;
00166 t.linear.x = v.x;
00167 t.linear.y = v.y;
00168
00169 pub.publish(t);
00170 }
00171
00172 void App2::publish_blue_cmd(const ros::TimerEvent&)
00173 {
00174 XY v = direction_blue();
00175 geometry_msgs::Twist t;
00176 t.linear.x = v.x;
00177 t.linear.y = v.y;
00178
00179 pub.publish(t);
00180 }
00181
00182 void App2::motion_red()
00183 {
00184 ros::NodeHandle nh;
00185 red_timer = nh.createTimer(ros::Duration(0.1), &App2::publish_red_cmd, this);
00186 }
00187
00188 void App2::motion_blue()
00189 {
00190 ros::NodeHandle nh;
00191 blue_timer = nh.createTimer(ros::Duration(0.1), &App2::publish_blue_cmd, this);
00192 }
00193
00194 void App2::baseCallback(const nav_msgs::Odometry& lmsg)
00195 {
00196 float x = lmsg.pose.pose.position.x;
00197 float y = lmsg.pose.pose.position.y;
00198
00199 float vx = lmsg.twist.twist.linear.x;
00200 float vy = lmsg.twist.twist.linear.y;
00201
00202 micros_swarm::Base l(x, y, 0, vx, vy, 0, 1);
00203 set_base(l);
00204 }
00205
00206 void App2::start()
00207 {
00208 init();
00209
00210 ros::NodeHandle nh;
00211 set_dis(40);
00212 pub = nh.advertise<geometry_msgs::Twist>("cmd_vel", 1000);
00213 sub = nh.subscribe("base_pose_ground_truth", 1000, &App2::baseCallback, this, ros::TransportHints().udp());
00214
00215 boost::function<bool()> bfred = boost::bind(&App2::red, this, get_id());
00216 boost::function<bool()> bfblue = boost::bind(&App2::blue, this, get_id());
00217
00218 micros_swarm::Swarm red_swarm(RED_SWARM);
00219 red_swarm.select(bfred);
00220 micros_swarm::Swarm blue_swarm(BLUE_SWARM);
00221 blue_swarm.select(bfblue);
00222
00223 red_swarm.print();
00224 blue_swarm.print();
00225
00226 red_swarm.execute(boost::bind(&App2::motion_red, this));
00227 blue_swarm.execute(boost::bind(&App2::motion_blue, this));
00228 }
00229 };