00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 from Tix import *
00025 import time
00026 import math
00027
00028
00029 import RTC
00030 import OpenRTM_aist
00031
00032
00033 tkmobilerobotsimulator_spec = ["implementation_id", "TkMobileRobotSimulator",
00034 "type_name", "TkMobileRobotSimulator",
00035 "description", "sample component for Python and Tkinter",
00036 "version", "1.0",
00037 "vendor", "Noriaki Ando, AIST",
00038 "category", "example",
00039 "activity_type", "DataFlowComponent",
00040 "max_instance", "10",
00041 "language", "Python",
00042 "lang_type", "SCRIPT",
00043 ""]
00044
00045
00046
00047 class TkMobileRobotSimulator(OpenRTM_aist.DataFlowComponentBase):
00048 def __init__(self, manager):
00049 OpenRTM_aist.DataFlowComponentBase.__init__(self, manager)
00050
00051 self.pos = []
00052 self.vel = []
00053 return
00054
00055 def onInitialize(self):
00056 self._d_vel = RTC.TimedFloatSeq(RTC.Time(0,0),[])
00057 self._velIn = OpenRTM_aist.InPort("vel", self._d_vel)
00058
00059 self._d_pos = RTC.TimedFloatSeq(RTC.Time(0,0),[])
00060 self._posOut = OpenRTM_aist.OutPort("pos", self._d_pos)
00061
00062
00063 self.addInPort("vel",self._velIn)
00064 self.addOutPort("pos",self._posOut)
00065
00066
00067 return RTC.RTC_OK
00068
00069 def onShutdown(self, ec_id):
00070 return RTC.RTC_OK
00071
00072 def onDeactivated(self, ec_id):
00073 self.pos = []
00074 self.vel = []
00075 return RTC.RTC_OK
00076
00077 def onExecute(self, ec_id):
00078 if self._velIn.isNew():
00079 self.vel = self._velIn.read().data
00080 self._d_pos.data = self.pos
00081 self._posOut.write()
00082 time.sleep(0.01)
00083 return RTC.RTC_OK
00084
00085 def get_velocity(self):
00086 return self.vel
00087
00088 def set_position(self, pos):
00089 self.pos = pos
00090
00091
00092 class ToggleItem:
00093 def __init__(self):
00094 self.active = True
00095 return
00096
00097 def __del__(self):
00098 self.delete()
00099 return
00100
00101 def activate(self):
00102 self.active = True
00103 self.draw()
00104 return
00105
00106 def deactivate(self):
00107 self.active = False
00108 self.delete()
00109 return
00110
00111 def toggle(self):
00112 if self.active:
00113 self.deactivate()
00114 else:
00115 self.activate()
00116 return
00117
00118 class CanvasText(ToggleItem):
00119 def __init__(self, canvas, text, x, y):
00120 ToggleItem.__init__(self)
00121 self.canvas = canvas
00122 self.id = self.canvas.create_text(x, y, text=text)
00123 self.text = text
00124 self.x = x
00125 self.y = y
00126 self.draw_text(x, y, text)
00127 return
00128
00129 def draw(self):
00130 if self.active == False: return
00131 self.delete()
00132 self.id = self.canvas.create_text(self.x, self.y, text=self.text)
00133 return
00134
00135 def draw_text(self, x, y, text):
00136 self.x = x
00137 self.y = y
00138 self.text = text
00139 self.draw()
00140 return
00141
00142 def delete(self):
00143 self.canvas.delete(self.id)
00144 return
00145
00146 class RobotTitle(ToggleItem):
00147 def __init__(self, simulator, robot, name, r):
00148 ToggleItem.__init__(self)
00149 self.canvas = simulator.get_canvas()
00150 self.trans = simulator.get_translation()
00151 self.robot = robot
00152 self.name = name
00153 self.r = r
00154 self.id_circle = None
00155 self.id_line0 = None
00156 self.id_line1 = None
00157 self.id_name = None
00158 self.id_pos = None
00159 self.llength = 50
00160 return
00161
00162 def draw(self):
00163 if self.active == False: return
00164 self.delete()
00165 rx, ry, rt = self.robot.get_pos()
00166
00167 tmp_x0 = - self.r
00168 tmp_y0 = - self.r
00169 tmp_x1 = self.r
00170 tmp_y1 = self.r
00171 x0, y0 = self.trans(tmp_x0, tmp_y0, rx, ry, 0)
00172 x1, y1 = self.trans(tmp_x1, tmp_y1, rx, ry, 0)
00173
00174 self.id_circle = self.canvas.create_oval(x0, y0, x1, y1,
00175 width=2,
00176 fill="", outline="#aaaaaa")
00177 r = (x1 - x0)/2
00178 xo = x0 + r
00179 yo = y0 - r
00180
00181 lx0 = xo + (r / math.sqrt(2))
00182 ly0 = yo - (r / math.sqrt(2))
00183 lx1 = lx0 + self.llength
00184 ly1 = ly0 - self.llength
00185
00186 self.id_line0 = self.canvas.create_line(lx0, ly0, lx1, ly1,
00187 fill="#777777")
00188 self.id_line1 = self.canvas.create_line(lx1, ly1, lx1 + 120, ly1,
00189 fill="#777777")
00190 self.id_name = self.canvas.create_text(lx1+120, ly1-8,
00191 anchor=E, text=self.name)
00192 pos_text = '(%5.2f, %5.2f, %5.2f)' % (rx, ry, (rt*180/math.pi)%360)
00193 self.id_pos = self.canvas.create_text(lx1+120, ly1+8,
00194 anchor=E, text=pos_text)
00195 return
00196
00197
00198 def delete(self):
00199 if self.id_circle != None:
00200 self.canvas.delete(self.id_circle)
00201 if self.id_line0 != None:
00202 self.canvas.delete(self.id_line0)
00203 if self.id_line1 != None:
00204 self.canvas.delete(self.id_line1)
00205 if self.id_name != None:
00206 self.canvas.delete(self.id_name)
00207 if self.id_pos != None:
00208 self.canvas.delete(self.id_pos)
00209 return
00210
00211
00212 class CanvasGrid(ToggleItem):
00213 def __init__(self, canvas, x0, y0, width, height, pitch, color, linewd):
00214 ToggleItem.__init__(self)
00215 self.canvas = canvas
00216 self.x0 = x0
00217 self.y0 = y0
00218 self.width = width
00219 self.height = height
00220 self.pitch = pitch
00221 self.color = color
00222 self.linewd = linewd
00223 self.idx = []
00224 self.idy = []
00225
00226 self.draw()
00227 return
00228
00229
00230 def draw(self):
00231 if self.active == False: return
00232 self.delete()
00233
00234 x_start = int(self.x0 % self.pitch)
00235 x_num = int((self.width - x_start) / self.pitch) + 1
00236 for x in range(x_num):
00237 x0 = x_start + self.pitch * x
00238 id = self.canvas.create_line(x0, 0, x0, self.height,
00239 fill=self.color, width=self.linewd)
00240 self.idx.append(id)
00241
00242 y_start = int(self.y0 % self.pitch)
00243 y_num = int((self.height - y_start) / self.pitch) + 1
00244 for y in range(y_num):
00245 y0 = y_start + self.pitch * y
00246 id = self.canvas.create_line(0, y0, self.width, y0,
00247 fill=self.color, width=self.linewd)
00248 self.idy.append(id)
00249
00250 for i in self.idx:
00251 self.canvas.tag_lower(i)
00252 for i in self.idy:
00253 self.canvas.tag_lower(i)
00254 return
00255
00256
00257 def delete(self):
00258 for i in self.idx:
00259 self.canvas.delete(i)
00260 for i in self.idy:
00261 self.canvas.delete(i)
00262 return
00263
00264
00265 def set_pitch(self, pitch):
00266 self.pitch = pitch
00267 self.draw()
00268 return
00269
00270
00271 class CanvasAxis(ToggleItem):
00272 def __init__(self, canvas, width, height):
00273 ToggleItem.__init__(self)
00274 self.x0 = width/2
00275 self.y0 = height/2
00276 self.width = width
00277 self.height = height
00278 self.canvas = canvas
00279 self.id = [None] * 4
00280 self.draw()
00281 return
00282
00283
00284 def draw(self):
00285 if self.active == False: return
00286 self.delete()
00287 self.id[0] = self.canvas.create_line(0, self.height/2,
00288 self.width, self.height/2)
00289 self.id[1] = self.canvas.create_text(self.width - 10,
00290 self.height/2 + 10,
00291 text="x")
00292 self.id[2] = self.canvas.create_line(self.width/2, 0,
00293 self.width/2, self.height)
00294 self.id[3] = self.canvas.create_text(self.width/2 + 10,
00295 + 10, text="y")
00296
00297 return
00298
00299 def delete(self):
00300 for i in self.id:
00301 self.canvas.delete(i)
00302 return
00303
00304
00305
00306 class SimulatedObject:
00307 def __init__(self, simulator):
00308 self.simulator = simulator
00309 self.tick = simulator.get_tick()
00310 self.canvas = simulator.get_canvas()
00311 self.trans = simulator.get_translation()
00312 return
00313
00314 def translate(self, x, y, dx, dy, dth):
00315 return self.trans(x, y, dx, dy, dth)
00316
00317 def get_tick(self):
00318 return self.simulator.get_tick()
00319
00320
00321 import tkSimpleDialog
00322
00323 class PropertyDialog:
00324 def __init__(self):
00325
00326 self.name = ""
00327 self.type = ""
00328 self.description = ""
00329 self.vendor = ""
00330
00331 self.param = []
00332 self.input = []
00333 self.output = []
00334
00335 self.label_len = 0
00336
00337 self.unit_len = 0
00338
00339 self.apply_param = None
00340 self.apply_input = None
00341 self.reset_output = None
00342 return
00343
00344 def set_profile(self, name, type, description, vendor):
00345 self.name = name
00346 self.type = type
00347 self.description = description
00348 self.vendor =vendor
00349 return
00350
00351 def append_parameter(self, label, variable, unit):
00352 self.param.append({"label":label, "var":variable, "unit":unit})
00353 self.label_len = max(len(label), self.label_len)
00354 self.unit_len = max(len(unit), self.unit_len)
00355 return
00356
00357 def append_input(self, label, variable, unit):
00358 self.input.append({"label":label, "var":variable, "unit":unit})
00359 self.label_len = max(len(label), self.label_len)
00360 self.unit_len = max(len(unit), self.unit_len)
00361 return
00362
00363 def append_output(self, label, variable, unit):
00364 self.output.append({"label":label, "var":variable, "unit":unit})
00365 self.label_len = max(len(label), self.label_len)
00366 self.unit_len = max(len(unit), self.unit_len)
00367 return
00368
00369 def set_apply_param(self, func):
00370 self.apply_param = func
00371 return
00372
00373 def set_apply_input(self, func):
00374 self.apply_input = func
00375 return
00376
00377 def set_reset_output(self, func):
00378 self.reset_output = func
00379 return
00380
00381 def pack(self):
00382 f = Toplevel()
00383 self.toplevel = f
00384 f.title(self.name)
00385 w0 = LabelFrame(f, label="Robot's Profile",
00386 options="frame.anchor w frame.justify left")
00387 prof_frame = w0.subwidget('frame')
00388 self.profile_label(prof_frame)
00389
00390 w1 = LabelFrame(f, label="Robot's Parameters")
00391 param_frame = w1.subwidget('frame')
00392 self.label_entries(param_frame, self.param)
00393 if self.apply_param != None:
00394 self.button(param_frame, "Apply", self.apply_param)
00395
00396 w2 = LabelFrame(f, label="Robot's Input Values")
00397 input_frame = w2.subwidget('frame')
00398 self.label_entries(input_frame, self.input)
00399 if self.apply_input != None:
00400 self.button(input_frame, "Set", self.apply_input)
00401
00402 w3 = LabelFrame(f, label="Robot's Output Values")
00403 output_frame = w3.subwidget('frame')
00404 self.label_entries(output_frame, self.output)
00405 if self.reset_output != None:
00406 self.button(output_frame, "Reset", self.reset_output)
00407
00408
00409 for w in [w0, w1, w2, w3]:
00410 w.pack(side=TOP, anchor=W, fill=X)
00411 self.button(f, "OK", self.on_ok)
00412
00413 return
00414
00415 def on_ok(self):
00416 self.toplevel.destroy()
00417 return
00418
00419
00420 def button(self, master, label, func):
00421 bt = Button(master, text=label, command=func, width=10,
00422 padx=3, pady=3)
00423 bt.pack(side=TOP, padx=5, pady=5)
00424 return
00425
00426
00427 def profile_label(self, master):
00428 t = ["Robot's name: ", "Robot's type: ", "Description: ", "Vendor: "]
00429 for i in range(len(t)):
00430 Label(master, text=t[i], anchor=W).grid(row=i, sticky=W,
00431 padx=3, pady=3)
00432 l = [self.name, self.type, self.description, self.vendor]
00433 for i in range(len(l)):
00434 Label(master, text=l[i], anchor=W).grid(row=i, column=1, sticky=W,
00435 padx=3, pady=3)
00436 return
00437
00438
00439 def label_entry(self, master, label0, var, label1):
00440 f = Frame(master)
00441 l0 = Label(f, text=label0, width=self.label_len, justify=LEFT, anchor=W)
00442 e = Entry(f, width=7, textvariable=var,
00443 justify=RIGHT, relief=GROOVE, bd=2)
00444 l1 = Label(f, text=label1, width=self.unit_len, justify=LEFT, anchor=W)
00445 for w in [l0, e, l1]:
00446 w.pack(side=LEFT, anchor=W, padx=3, pady=3)
00447 return f
00448
00449 def label_entries(self, f, props):
00450 for p in props:
00451 self.label_entry(f, p["label"], p["var"], p["unit"]).pack(side=TOP)
00452 return
00453
00454
00455
00456 class DiffMobileModel:
00457 def __init__(self, radius, wheeld, pos = (0, 0, math.pi/2), dt=0.1):
00458 self.radius = radius
00459 self.wheeld = wheeld
00460 self.dt = dt
00461 self.pre_x = pos[0]
00462 self.pre_y = pos[1]
00463 self.pre_t = pos[2]
00464 self.pre_x_dot = 0
00465 self.pre_y_dot = 0
00466 self.pre_t_dot = 0
00467 return
00468
00469
00470 def set_wheel_radius(self, radius):
00471
00472 self.radius = radius
00473 return
00474
00475
00476 def set_wheel_distance(self, distance):
00477
00478 self.wheeld = distance
00479 return
00480
00481
00482 def set_time_tick(self, tick):
00483
00484 self.dt = tick
00485 return
00486
00487
00488 def set_pos(self, pos = (0, 0, math.pi/2)):
00489
00490
00491
00492 self.pre_x = pos[0]
00493 self.pre_y = pos[1]
00494 self.pre_t = pos[2]
00495 return
00496
00497
00498 def get_pos(self):
00499 return self.pre_x, self.pre_y, self.pre_t
00500
00501 def control(self, w1, w2):
00502
00503
00504 x_dot = self.radius * (w1 + w2) * math.cos(self.pre_t)
00505 y_dot = self.radius * (w1 + w2) * math.sin(self.pre_t)
00506 t_dot = self.radius * (-w1 + w2) / self.wheeld
00507
00508 x = (self.dt * (self.pre_x_dot + x_dot) / 2) + self.pre_x
00509 y = (self.dt * (self.pre_y_dot + y_dot) / 2) + self.pre_y
00510 theta = (self.dt * (self.pre_t_dot + t_dot) / 2) + self.pre_t
00511
00512 self.pre_x = x
00513 self.pre_y = y
00514 self.pre_t = theta
00515
00516 self.pre_x_dot = x_dot
00517 self.pre_y_dot = y_dot
00518 self.pre_t_dot = t_dot
00519
00520 return x, y, theta
00521
00522
00523
00524 class DDMobileRobot(SimulatedObject):
00525 count = 0
00526 def __init__(self, simulator, radius=2, wheeld=20,
00527 pos = (0, 0, math.pi/2)):
00528 SimulatedObject.__init__(self, simulator)
00529 self.tick = self.get_tick()
00530 self.model = DiffMobileModel(radius, wheeld, pos, self.tick)
00531 self.fig = [[10, 0], [5, 10], [-10, 10], [-10, -10], [5, -10]]
00532 self.id = None
00533 self.wl = 0.0
00534 self.wr = 0.0
00535 self.name = "DDMobileRobot" + str(self.__class__.count)
00536 self.__class__.count += 1
00537 self.comp = OpenRTM_aist.Manager.instance().createComponent("TkMobileRobotSimulator")
00538
00539
00540 self.rentry = StringVar()
00541 self.rentry.set(radius)
00542 self.dentry = StringVar()
00543 self.dentry.set(wheeld)
00544
00545 self.wlentry = StringVar()
00546 self.wrentry = StringVar()
00547
00548 self.xentry = StringVar()
00549 self.yentry = StringVar()
00550 self.tentry = StringVar()
00551 return
00552
00553
00554 def __del__(self):
00555 try:
00556 self.comp.exit()
00557 del self.comp
00558 except:
00559 pass
00560 self.delete()
00561 return
00562
00563
00564 def get_name(self):
00565 return self.name
00566
00567
00568 def set_pos(self, (x, y, th)):
00569 self.model.set_pos((x, y, th))
00570 return
00571
00572
00573 def get_pos(self):
00574 return self.model.get_pos()
00575
00576
00577 def set_wheel_velocity(self, wl, wr):
00578 self.wl = wl
00579 self.wr = wr
00580 self.wlentry.set('%5.2f'%self.wl)
00581 self.wrentry.set('%5.2f'%self.wr)
00582 return
00583
00584
00585 def on_update(self):
00586 self.model.set_time_tick(self.get_tick())
00587 v = self.comp.get_velocity()
00588 if len(v) == 2:
00589 self.set_wheel_velocity(v[0], v[1])
00590 self.x, self.y, self.th = self.model.control(self.wl, self.wr)
00591 self.th_deg = (self.th * 180 / math.pi) % 360
00592 self.comp.set_position((self.x, self.y, self.th_deg))
00593 self.xentry.set('%5.2f'%self.x)
00594 self.yentry.set('%5.2f'%self.y)
00595 self.tentry.set('%5.2f'%self.th_deg)
00596 self.draw()
00597 return
00598
00599
00600 def draw(self):
00601
00602
00603 robotfig = []
00604 for pos in self.fig:
00605 robotfig.append(self.translate(pos[0], pos[1],
00606 self.x, self.y, self.th))
00607 if self.id != None:
00608 self.canvas.delete(self.id)
00609 self.id = self.canvas.create_polygon(robotfig,
00610 fill="#00aa00",
00611 outline="#eeeeee")
00612 return
00613
00614
00615 def delete(self):
00616 if self.id != None:
00617 self.canvas.delete(self.id)
00618 return
00619
00620
00621 def property_page(self):
00622 p = PropertyDialog()
00623 p.set_profile(self.name, "DDMobileRobot",
00624 "Differential Drive Mobile Robot", "AIST")
00625 p.append_parameter("Wheel radius r: ", self.rentry, "[m]")
00626 p.append_parameter("Wheel distance d: ", self.dentry, "[m]")
00627 p.append_input("Angular velocity (LEFT) wl: ", self.wlentry, "[rad/s]")
00628 p.append_input("Angular velocity (RIGHT) wr: ", self.wrentry, "[rad/s]")
00629 p.append_output("Robot position x : ", self.xentry, "[m]")
00630 p.append_output("Robot position y : ", self.yentry, "[m]")
00631 p.append_output("Robot position th: ", self.tentry, "[deg]")
00632 p.set_apply_param(self.on_apply_param)
00633 p.set_apply_input(self.on_apply_input)
00634 p.set_reset_output(self.on_reset_output)
00635 p.pack()
00636 return
00637
00638
00639 def on_reset_output(self):
00640 self.set_pos((0.0, 0.0, math.pi/2))
00641 return
00642
00643
00644 def on_apply_param(self):
00645 r = float(self.rentry.get())
00646 d = float(self.dentry.get())
00647 self.model.set_wheel_radius(r)
00648 self.model.set_wheel_distance(d)
00649 return
00650
00651
00652 def on_apply_input(self):
00653 self.wl = float(self.wlentry.get())
00654 self.wr = float(self.wrentry.get())
00655 return
00656
00657
00658
00659
00660 class TkMobileRobot(Frame):
00661 def __init__(self, master=None, width=800, height=600):
00662 Frame.__init__(self, master)
00663
00664
00665 self.width = width
00666 self.height = height
00667
00668 self.x0 = width/2
00669 self.y0 = height/2
00670
00671 self.wd = 150
00672
00673 self.robots = {}
00674
00675 self.robot = None
00676 self.postext = None
00677
00678 self.scale = 1.0
00679 self.scale_var = DoubleVar()
00680 self.scale_var.set(self.scale)
00681
00682 self.grid_pitch = 50
00683
00684 self.tick = 0.1
00685 self.default_tick = 0.1
00686 self.tickscale_var = DoubleVar()
00687 self.tickscale_var.set(self.tick)
00688
00689 self.axis_check = StringVar()
00690 self.axis_check.set("on")
00691 self.grid_check = StringVar()
00692 self.grid_check.set("on")
00693 self.rname_check = StringVar()
00694 self.rname_check.set("on")
00695 self.rnames = {}
00696
00697 self.robot_kind_var = StringVar()
00698 self.robot_factory = {"DDMobileRobot": DDMobileRobot}
00699
00700
00701
00702 self.init()
00703 self.pack()
00704
00705
00706 self.after(20, self.on_update)
00707 return
00708
00709 def init(self):
00710 self.canvas = Canvas(self, bg="#eeeeee",
00711 width = self.width, height = self.height)
00712 self.canvas.pack(side=LEFT)
00713
00714 self.can_grid = CanvasGrid(self.canvas, self.x0, self.y0,
00715 self.width, self.height, self.grid_pitch,
00716 "#aaaaaa", 1)
00717 self.can_axis = CanvasAxis(self.canvas, self.width, self.height)
00718
00719 self.frame = Frame(self)
00720 self.frame.pack(side=LEFT)
00721
00722
00723 self.scrctrl_frame = Frame(self.frame, width=self.wd, height=300,
00724 relief=GROOVE, bd=2)
00725 self.scrctrl_frame.pack(side=TOP, fill=X)
00726 self.create_scale(self.scrctrl_frame)
00727 self.create_checkbutton(self.scrctrl_frame)
00728
00729
00730 self.robomgr_frame = Frame(self.frame, width=self.wd, height=300,
00731 relief=GROOVE, bd=2)
00732 self.robomgr_frame.pack(side=TOP)
00733 self.create_robotcreator(self.robomgr_frame)
00734 self.create_robotlist(self.robomgr_frame)
00735 return
00736
00737
00738 def on_update(self):
00739 for o in self.robots.keys():
00740 self.robots[o].on_update()
00741 for r in self.rnames.keys():
00742 self.rnames[r].draw()
00743 self.after(20, self.on_update)
00744 return
00745
00746
00747 def get_tick(self):
00748 return self.tick
00749
00750
00751 def get_canvas(self):
00752 return self.canvas
00753
00754
00755 def get_translation(self):
00756 return self.real_to_canvas
00757
00758
00759
00760
00761 def create_scale(self, frame):
00762 dummy = Frame(frame, width=self.wd)
00763 dummy.pack(side=TOP)
00764 sl = Scale(frame, from_=0, to=10, resolution=0.01,
00765 label="Scale Factor", command=self.on_scale,
00766 variable=self.scale_var, orient=HORIZONTAL)
00767 bt = Button(frame, text="Reset Scale", command=self.reset_scale)
00768 sl.pack(side=TOP, fill=X)
00769 bt.pack(side=TOP, fill=X)
00770
00771 sl = Scale(frame, from_=0.001, to=1, resolution=0.001,
00772 label="Time tick [s]", command=self.on_tickchange,
00773 variable=self.tickscale_var, orient=HORIZONTAL)
00774 bt = Button(frame, text="Reset Tick", command=self.reset_tickscale)
00775 sl.pack(side=TOP, fill=X)
00776 bt.pack(side=TOP, fill=X)
00777 return
00778
00779
00780 def on_scale(self, val):
00781 v = float(val)
00782 if v == 0.0:
00783 pitch = 0
00784 else:
00785 pitch = self.grid_pitch/v
00786 self.scale = v
00787 self.can_grid.set_pitch(pitch)
00788 return
00789
00790
00791 def reset_scale(self):
00792 self.scale_var.set(1.)
00793 pitch = self.grid_pitch/1.0
00794 self.scale = 1.0
00795 self.can_grid.set_pitch(pitch)
00796 return
00797
00798
00799 def on_tickchange(self, val):
00800 v = self.tickscale_var.get()
00801 if v == 0.0:
00802 self.tick = 0
00803 else:
00804 self.tick = v
00805 return
00806
00807 def reset_tickscale(self):
00808 self.tick = self.default_tick
00809 self.tickscale_var.set(self.default_tick)
00810 return
00811
00812
00813
00814
00815
00816 def create_checkbutton(self, frame):
00817 axis = Checkbutton(frame, text="Axis",
00818 onvalue="on", offvalue="off",
00819 justify=LEFT, anchor=W,
00820 variable=self.axis_check,
00821 command=self.can_axis.toggle)
00822 grid = Checkbutton(frame, text="Grid",
00823 onvalue="on", offvalue="off",
00824 justify=LEFT, anchor=W,
00825 variable=self.grid_check,
00826 command=self.can_grid.toggle)
00827 rname = Checkbutton(frame, text="Robots' name",
00828 onvalue="on", offvalue="off",
00829 justify=LEFT, anchor=W,
00830 variable=self.rname_check,
00831 command=self.on_rname_toggle)
00832 for w in [axis, grid, rname]:
00833 w.pack(side=TOP, anchor=W, fill=X)
00834 return
00835
00836
00837 def on_rname_toggle(self):
00838 for r in self.rnames.keys():
00839 self.rnames[r].toggle()
00840 return
00841
00842
00843
00844
00845
00846
00847
00848
00849 def create_robotcreator(self, frame):
00850 lb = Label(frame, text="Robot Type", anchor=W, justify=LEFT)
00851
00852 om = OptionMenu(frame, label="Type: ", variable=self.robot_kind_var)
00853 for opt in self.robot_factory.keys():
00854 om.add_command(opt, label=opt)
00855 self.robot_kind_var.set(self.robot_factory.keys()[0])
00856
00857 creater = Button(frame, text="Create", command=self.create_robot)
00858 deleter = Button(frame, text="Delete", command=self.delete_robot)
00859
00860 om.pack(side=TOP, fill=X)
00861 creater.pack(side=TOP, fill=X)
00862 deleter.pack(side=TOP, fill=X)
00863 return
00864
00865
00866 def create_robotlist(self, frame):
00867 f = Frame(frame, width=self.wd, height=200)
00868 f.pack(side=TOP, fill=BOTH, expand=1)
00869 ys = Scrollbar(f, orient = VERTICAL)
00870 ys.grid(row = 0, column=1, sticky = N+S)
00871 xs = Scrollbar(f, orient = HORIZONTAL)
00872 xs.grid(row = 1, column=0, sticky = E+W)
00873
00874 self.rlistbox = Listbox(f,
00875 xscrollcommand = xs.set,
00876 yscrollcommand = ys.set,
00877 selectmode = 'single',
00878 setgrid = TRUE,
00879 height=20)
00880 self.rlistbox.grid(row = 0, column = 0, sticky = N+S+E+W,)
00881 xs['command']=self.rlistbox.xview
00882 ys['command']=self.rlistbox.yview
00883 self.rlistbox.bind("<Double-Button-1>", self.on_clickrlistbox)
00884 return
00885
00886
00887 def on_clickrlistbox(self, event):
00888 index = self.rlistbox.curselection()
00889 if len(index) > 0:
00890 robot_name = self.rlistbox.get(index[0])
00891 self.robots[robot_name].property_page()
00892 return
00893
00894
00895 def create_robot(self):
00896 kind = self.robot_kind_var.get()
00897 robot = self.robot_factory[kind](self)
00898
00899 self.rlistbox.insert(END, robot.get_name())
00900 self.rnames[robot.get_name()] = RobotTitle(self,
00901 robot,
00902 robot.get_name(),
00903 20)
00904 self.robots[robot.get_name()] = robot
00905 return
00906
00907
00908 def delete_robot(self):
00909 index = self.rlistbox.curselection()
00910 if len(index) > 0:
00911 robot_name = self.rlistbox.get(index[0])
00912 r = self.rnames.pop(robot_name)
00913 del(r)
00914 r = self.robots.pop(robot_name)
00915 del(r)
00916 self.rlistbox.delete(index)
00917 return
00918
00919
00920
00921
00922
00923
00924
00925 def real_to_canvas(self, x, y, dx, dy, dt):
00926
00927
00928
00929
00930 x_tmp = (math.cos(dt) * x - math.sin(dt) * y + dx)/self.scale
00931 y_tmp = (math.sin(dt) * x + math.cos(dt) * y + dy)/self.scale
00932
00933 xo = x_tmp + self.x0
00934 yo = -y_tmp + self.y0
00935 return xo, yo
00936
00937
00938 def TkMobileRobotSimulatorInit(manager):
00939 profile = OpenRTM_aist.Properties(defaults_str=tkmobilerobotsimulator_spec)
00940 manager.registerFactory(profile,
00941 TkMobileRobotSimulator,
00942 OpenRTM_aist.Delete)
00943 return
00944
00945
00946 def main():
00947 m = TkMobileRobot(Tk())
00948 m.master.title("Tk Mobile Robot Simulator")
00949 mgr = OpenRTM_aist.Manager.init(sys.argv)
00950 mgr.activateManager()
00951 profile = OpenRTM_aist.Properties(defaults_str=tkmobilerobotsimulator_spec)
00952 mgr.registerFactory(profile, TkMobileRobotSimulator, OpenRTM_aist.Delete)
00953 mgr.runManager(True)
00954 m.mainloop()
00955
00956 if __name__ == '__main__':
00957 main()