Go to the documentation of this file.00001
00009 #include <youbot_overhead_localization/localizer.h>
00010
00011 localizer::localizer()
00012 {
00013 std::string odomTopicName;
00014
00015 odometryInitialized = false;
00016 pose.x = 0;
00017 pose.y = 0;
00018 pose.theta = 0;
00019
00020 P[0] = .5;
00021 P[1] = .5;
00022 P[2] = .5;
00023
00024 Q[0] = Q_X;
00025 Q[1] = Q_Y;
00026 Q[2] = Q_T;
00027
00028 R[0] = R_X;
00029 R[1] = R_Y;
00030 R[2] = R_T;
00031
00032 n.getParam("/base_localizer/odomTopic", odomTopicName);
00033
00034
00035 baseOdometrySubscriber = n.subscribe(odomTopicName, 0, &localizer::baseOdometryCallback, this);
00036 positionFromCameraSubscriber = n.subscribe("/image_calibration/position_from_camera", 1,
00037 &localizer::positionFromCameraCallback, this);
00038 baseLocalizationPublisher = n.advertise<youbot_overhead_localization::Pose2d>("base_localizer/pose_2d", 1);
00039 coordConversionClient = n.serviceClient<youbot_overhead_vision::CoordConversion>("coord_conversion");
00040 }
00041
00042 void localizer::baseOdometryCallback(const nav_msgs::Odometry& odometry)
00043 {
00044 if (!odometryInitialized)
00045 {
00046 lastReceivedOdometry = odometry;
00047 odometryInitialized = true;
00048 }
00049 else
00050 {
00051 float u[3];
00052 float B[3][3];
00053 double timePassed = (odometry.header.stamp - lastReceivedOdometry.header.stamp).toSec();
00054
00055 u[0] = odometry.twist.twist.linear.x * timePassed;
00056 u[1] = odometry.twist.twist.linear.y * timePassed;
00057 u[2] = odometry.twist.twist.angular.z * timePassed;
00058
00059 B[0][0] = cos(pose.theta);
00060 B[0][1] = sin(pose.theta);
00061 B[0][2] = 0.0;
00062 B[1][0] = -sin(pose.theta);
00063 B[1][1] = cos(pose.theta);
00064 B[1][2] = 0.0;
00065 B[2][0] = 0.0;
00066 B[2][1] = 0.0;
00067 B[2][2] = 1.0;
00068
00069
00070
00071 pose.x += u[0] * B[0][0] + u[1] * B[1][0] + u[2] * B[2][0];
00072 pose.y += u[0] * B[0][1] + u[1] * B[1][1] + u[2] * B[2][1];
00073 pose.theta += u[0] * B[0][2] + u[1] * B[1][2] + u[2] * B[2][2];
00074
00075
00076 pose.theta = convertAngle(pose.theta);
00077
00078
00079 P[0] += Q[0];
00080 P[1] += Q[1];
00081 P[2] += Q[2];
00082
00083 baseLocalizationPublisher.publish(pose);
00084
00085 lastReceivedOdometry = odometry;
00086 }
00087 }
00088
00089 void localizer::positionFromCameraCallback(const youbot_overhead_vision::PositionFromCamera& newPos)
00090 {
00091 float y[3];
00092 float J[3];
00093 float heading = (float)(newPos.heading);
00094 int posx = newPos.midpointX;
00095 int posy = newPos.midpointY;
00096
00097 youbot_overhead_vision::CoordConversion srv;
00098 srv.request.x = posx;
00099 srv.request.y = posy;
00100 srv.request.type = 1;
00101 coordConversionClient.call(srv);
00102
00103 y[0] = srv.response.xConverted - pose.x;
00104 y[1] = srv.response.yConverted - pose.y;
00105 y[2] = convertAngle(heading - pose.theta);
00106
00107
00108
00109 J[0] = P[0] * (1.0 / (P[0] + R[0]));
00110 J[1] = P[1] * (1.0 / (P[1] + R[1]));
00111 J[2] = P[2] * (1.0 / (P[2] + R[2]));
00112
00113
00114 pose.x = pose.x + J[0] * y[0];
00115 pose.y = pose.y + J[1] * y[1];
00116 pose.theta = convertAngle(pose.theta + J[2] * y[2]);
00117
00118
00119 P[0] = (1.0 - J[0]) * P[0];
00120 P[1] = (1.0 - J[1]) * P[1];
00121 P[2] = (1.0 - J[2]) * P[2];
00122
00123 baseLocalizationPublisher.publish(pose);
00124 }
00125
00126 float localizer::convertAngle(float theta)
00127 {
00128 while (theta > PI)
00129 {
00130 theta -= 2 * PI;
00131 }
00132 while (theta < -PI)
00133 {
00134 theta += 2 * PI;
00135 }
00136
00137 return theta;
00138 }
00139
00143 int main(int argc, char **argv)
00144 {
00145 ros::init(argc, argv, "base_localizer");
00146
00147 localizer baseLocalizer;
00148
00149 ros::spin();
00150
00151 return 0;
00152 }
00153