diff --git a/waypoint_manager/scripts/devel_GUI.py b/waypoint_manager/scripts/devel_GUI.py index dbb636a..5e3168f 100755 --- a/waypoint_manager/scripts/devel_GUI.py +++ b/waypoint_manager/scripts/devel_GUI.py @@ -21,10 +21,12 @@ self.menu_bar.add_cascade(label="File", menu=self.file_menu) # Fileメニューとしてバーに追加 self.file_menu.add_command(label="Save", # FileメニューにSaveコマンドを追加 command=self.menu_save_clicked, #コールバック関数を設定 - accelerator="Ctrl+S") # 右側に表示するキーボードショートカット + accelerator="Ctrl+S"# 右側に表示するキーボードショートカット + ) self.file_menu.add_command(label="Save As", # 同様にSave Asコマンドを追加 command=self.menu_saveas_clicked, - accelerator="Ctrl+Shift+S") + accelerator="Ctrl+Shift+S" + ) self.bind_all("", self.menu_save_clicked) #キーボードショートカットを設定 self.bind_all("", self.menu_saveas_clicked) self.master.config(menu=self.menu_bar) # 大元に作成したメニューバーを設定 @@ -34,25 +36,30 @@ self.__waypoints = self.get_waypoints() ## canvasを配置 - self.canvas = tk.Canvas(self.master, background="#008B8B") # 画像を描画するcanvas + self.canvas = tk.Canvas(self.master, background="#a0a0a0") # 画像を描画するcanvas self.canvas.pack(expand=True, fill=tk.BOTH) # canvasを配置 self.update() # 情報の更新をする(canvasのサイズなどの情報が更新される) ## 画像をcanvasのサイズにフィッティングして描画 - canv_w = self.canvas.winfo_width() # canvasの幅を取得 - canv_h = self.canvas.winfo_height() # canvasの高さを取得 - if (canv_w / canv_h) > (self.__map_img_pil.width / self.__map_img_pil.height): + self.canv_w = self.canvas.winfo_width() # canvasの幅を取得 + self.canv_h = self.canvas.winfo_height() # canvasの高さを取得 + self.mat_affine = np.eye(3) + scale = 1 + offset_x = 0 + offset_y = 0 + if (self.canv_w / self.canv_h) > (self.__map_img_pil.width / self.__map_img_pil.height): # canvasの方が横長 画像をcanvasの縦に合わせてリサイズ - scale = canv_h / self.__map_img_pil.height - img_w = int(self.__map_img_pil.width * scale) - img = self.__map_img_pil.resize((img_w, canv_h), resample=Image.Resampling.NEAREST) + scale = self.canv_h / self.__map_img_pil.height + offset_x = (self.canv_w - self.__map_img_pil.width*scale) / 2 else: # canvasの方が縦長 画像をcanvasの横に合わせてリサイズ - scale = canv_w / self.__map_img_pil.width - img_h = int(self.__map_img_pil.height * scale) - img = self.__map_img_pil.resize((canv_w, img_h), resample=Image.Resampling.NEAREST) - self.draw_img_tk = ImageTk.PhotoImage(img) # pilフォーマットの画像をtkinterのフォーマットに変換 - self.canvas.create_image(canv_w/2, canv_h/2, image=self.draw_img_tk) # 画像の描画 + scale = self.canv_w / self.__map_img_pil.width + offset_y = (self.canv_h - self.__map_img_pil.height*scale) / 2 + + self.mat_affine = self.scale_mat(scale, self.mat_affine) + self.mat_affine = self.translate_mat(offset_x, offset_y, self.mat_affine) + self.draw_img_tk = self.draw_image(self.mat_affine) + self.canvas.create_image(0,0, anchor='nw', image=self.draw_img_tk) # 画像の描画 ## 右クリックしたときに表示するポップアップメニューを作成 self.popup_menu = tk.Menu(self, tearoff=tk.OFF) @@ -64,9 +71,20 @@ self.master.bind("", self.left_click_move) self.master.bind("", self.left_click) self.master.bind("", self.right_click) + + ## ウィンドウに関するコールバック + # self.master.bind("", self.window_resize_callback) + + self.plot_origin() return + #--- 地図上の原点に円を描画する --- + def plot_origin(self): + origin = self.__map_yaml['origin'] # originは地図上の原点から画像の左下までの + return + + #--- mapのファイルパスを受け取り、map画像とmapの設定ファイルを読み込む --- #--- 今はパスを直接指定して読み込んでいるので、rospy.get_param()を使って読み込めるように --- @@ -105,7 +123,7 @@ #--- マウスホイールを回転したとき(タッチパッドをドラッグしたとき)のコールバック関数 --- - #--- docker コンテナ上だとtkinterでマウスホイールイベントが拾えないっぽいので、これは使いえないかも --- + #--- docker コンテナ上だとtkinterでマウスホイールイベントが拾えないっぽいので、これは使えないかも --- def mouse_wheel(self, event): if event.delta > 0: # 上に回転(タッチパッドなら下にドラッグ)=> 拡大 @@ -143,6 +161,47 @@ def left_click(self, event): self.popup_menu.unpost() + + + #--- mat_affineにx,yの平行移動を加えた同次変換行列を返す --- + def translate_mat(self, x, y, mat_affine): + mat = np.eye(3) + mat[0, 2] = float(x) + mat[1, 2] = float(y) + return np.dot(mat, mat_affine) + + #--- mat_affineにscale倍のリサイズを加えた同次変換行列を返す --- + def scale_mat(self, scale, mat_affine): + mat = np.eye(3) + mat[0, 0] = scale + mat[1, 1] = scale + return np.dot(mat, mat_affine) + + + def draw_image(self, mat_affine): + mat_inv = np.linalg.inv(mat_affine) + img = self.__map_img_pil.transform( + (self.canv_w, self.canv_w), + Image.Transform.AFFINE, tuple(mat_inv.flatten()), + Image.Resampling.NEAREST, + fillcolor = 160 + ) + tk_img = ImageTk.PhotoImage(image=img) + self.canvas.create_image(0, 0, anchor='nw', image=tk_img) # 画像の描画 + return tk_img + + + #--- + def window_resize_callback(self, event): + cw = self.canvas.winfo_width() + ch = self.canvas.winfo_height() + if (self.canv_w != cw) or (self.canv_h != ch): + self.canv_w = cw + self.canv_h = ch + self.canvas.delete("all") + self.canvas.create_image(self.canv_w/2, self.canv_h/2, image=self.draw_img_tk) + return +