38 from __future__
import with_statement
40 import roslib; roslib.load_manifest(
'turtlebot_calibration')
44 from sensor_msgs.msg
import Imu
45 from nav_msgs.msg
import Odometry
46 from geometry_msgs.msg
import Twist
47 from turtlebot_calibration.msg
import ScanAngle
50 import dynamic_reconfigure.client
56 rot = PyKDL.Rotation.Quaternion(quat.x, quat.y, quat.z, quat.w)
57 return rot.GetRPY()[2]
70 self.
lock = threading.Lock()
72 self.
has_gyro = rospy.get_param(
"turtlebot_node/has_gyro")
73 rospy.loginfo(
'has_gyro %s'%self.
has_gyro)
79 self.
cmd_pub = rospy.Publisher(
'cmd_vel', Twist)
96 (imu_start_angle, odom_start_angle, scan_start_angle,
97 imu_start_time, odom_start_time, scan_start_time) = self.
sync_timestamps()
98 last_angle = odom_start_angle
100 while turn_angle < 2*pi:
101 if rospy.is_shutdown():
104 cmd.angular.z = speed
105 self.cmd_pub.publish(cmd)
109 turn_angle += delta_angle
111 self.cmd_pub.publish(Twist())
113 (imu_end_angle, odom_end_angle, scan_end_angle,
119 rospy.loginfo(
'Odom error: %f percent'%(100.0*((odom_delta/scan_delta)-1.0)))
122 imu_delta = 2*pi +
normalize_angle(imu_end_angle - imu_start_angle) - imu_drift*(imu_end_time - imu_start_time).to_sec()
123 rospy.loginfo(
'Imu error: %f percent'%(100.0*((imu_delta/scan_delta)-1.0)))
124 imu_result = imu_delta/scan_delta
128 return (imu_result, odom_delta/scan_delta)
135 rospy.loginfo(
'Estimating imu drift')
136 (imu_start_angle, odom_start_angle, scan_start_angle,
137 imu_start_time, odom_start_time, scan_start_time) = self.
sync_timestamps()
139 (imu_end_angle, odom_end_angle, scan_end_angle,
142 imu_drift =
normalize_angle(imu_end_angle - imu_start_angle) / ((imu_end_time - imu_start_time).to_sec())
143 rospy.loginfo(
' ... imu drift is %f degrees per second'%(imu_drift*180.0/pi))
149 rospy.loginfo(
"Aligning base with wall")
155 if rospy.is_shutdown():
161 self.cmd_pub.publish(cmd)
170 start_time = rospy.Time.now() + rospy.Duration(0.5)
171 while not rospy.is_shutdown():
175 rospy.loginfo(
"Still waiting for imu")
177 rospy.loginfo(
"Still waiting for odom")
179 rospy.loginfo(
"Still waiting for scan")
200 angle = msg.scan_angle
205 usbpath = subprocess.check_output(
"readlink -f /sys/class/tty/ttyUSB0", shell=
True)
206 usbpath = usbpath.strip()
207 if len(usbpath) == 0:
211 f = open(usbpath +
"/../../../../serial",
"r") 212 serialid = f.read().strip() 217 f = open(usbpath +
"/../../../../idVendor",
"r") 218 serialid += f.read().strip() 220 f = open(usbpath + "/../../../../idProduct",
"r") 221 serialid += f.read().strip() 225 if len(serialid.strip()) == 0:
230 ret = subprocess.check_output(
"lsusb -v -d 045e:02ae | grep Serial | awk '{print $3}'", shell=
True)
236 allparams = drclient.get_configuration()
237 return (allparams[
'gyro_scale_correction'], allparams[
'odom_angular_scale_correction'], allparams[
'gyro_measurement_range'])
240 r = drclient.update_configuration(newparams)
241 rospy.loginfo(
"Automatically updated the params in the current running instance of ROS, no need to restart.")
245 if kinect_serial
is None:
247 if kinect_serial
is None:
249 ros_home = os.environ.get(
'ROS_HOME')
252 calib_dir = os.path.expanduser(ros_home +
"/turtlebot_create/")
253 calib_file = calib_dir +str(kinect_serial) +
".yaml" 255 if os.path.isfile(calib_file):
256 f = open(calib_file,
'r') 257 docs = yaml.load_all(f) 259 for k,v
in newparams.iteritems():
264 os.makedirs(calib_dir)
267 with open(calib_file,
'w')
as outfile:
268 outfile.write( yaml.dump(newparams, default_flow_style=
False) )
269 rospy.loginfo(
"Saved the params to the calibration file: %s" % calib_file)
273 f = open(
"/etc/ros/distro/turtlebot.launch",
"r") 277 if "turtlebot_node/gyro_scale_correction" in lines:
278 foo.append(
" <param name=\"turtlebot_node/gyro_scale_correction\" value=\"%f\"/>\n" % gyro)
279 elif "turtlebot_node/odom_angular_scale_correction" in lines:
280 foo.append(
" <param name=\"turtlebot_node/odom_angular_scale_correction\" value=\"%f\"/>\n" % odom)
281 elif "turtlebot_node/gyro_measurement_range" in lines:
282 foo.append(
" <param name=\"turtlebot_node/gyro_measurement_range\" value=\"%f\"/>\n" % gyro_range)
288 f = open(
"/etc/ros/distro/turtlebot.launch",
"w")
292 rospy.loginfo(
"Automatically updated turtlebot.launch, please restart the turtlebot service.")
294 rospy.loginfo(
"Could not automatically update turtlebot.launch, please manually update it.")
298 rospy.logwarn(
"***** If you have not manually set the gyro range parameter you must do so before running calibration. Cancel this run and see http://wiki.ros.org/turtlebot_calibration/Tutorials/Calibrate%20Odometry%20and%20Gyro")
299 rospy.logwarn(
"******* turtlebot_node/gyro_measurement_range is currently set to: %d ******" % params[2])
303 rospy.init_node(
'scan_to_angle')
307 drclient = dynamic_reconfigure.client.Client(
"turtlebot_node")
310 imu_drift = robot.imu_drift()
313 for speed
in (0.3, 0.7, 1.0, 1.5):
315 (imu, odom) = robot.calibrate(speed, imu_drift)
318 odom_corr.append(odom)
322 imu_res = prev_gyro * (1.0/(sum(imu_corr)/len(imu_corr)))
323 rospy.loginfo(
"Set the 'turtlebot_node/gyro_scale_correction' parameter to %f"%imu_res)
325 odom_res = prev_odom * (1.0/(sum(odom_corr)/len(odom_corr)))
326 rospy.loginfo(
"Set the 'turtlebot_node/odom_angular_scale_correction' parameter to %f"%odom_res)
329 newparams = {
'gyro_scale_correction' : imu_res,
'odom_angular_scale_correction' : odom_res,
'gyro_measurement_range' : gyro_range}
333 if __name__ ==
'__main__':
def get_usb_to_serial_id()
def warnAboutGyroRange(drclient)
def writeParams(drclient, newparams)
def writeParamsToCalibrationFile(newparams)
def writeParamsToLaunchFile(gyro, odom, gyro_range)
def sync_timestamps(self, start_time=None)
def getCurrentParams(drclient)
def calibrate(self, speed, imu_drift=0)
def normalize_angle(angle)