From 46447a928d4042d2385b4ce5dac8ceacfa6708a6 Mon Sep 17 00:00:00 2001 From: Isabel Paredes Date: Mon, 22 Aug 2022 18:48:53 +0200 Subject: [PATCH 1/3] Clean up --- jupyros/__init__.py | 1 - jupyros/ros2/key_input.py | 85 +++++++++++++-------------------------- 2 files changed, 29 insertions(+), 57 deletions(-) diff --git a/jupyros/__init__.py b/jupyros/__init__.py index 3f6804e..3e2b9bc 100644 --- a/jupyros/__init__.py +++ b/jupyros/__init__.py @@ -8,7 +8,6 @@ from ._version import __version__ import os -import rclpy try: ros_version = os.environ['ROS_VERSION'] diff --git a/jupyros/ros2/key_input.py b/jupyros/ros2/key_input.py index ec8b3e8..c1ab28f 100644 --- a/jupyros/ros2/key_input.py +++ b/jupyros/ros2/key_input.py @@ -10,33 +10,27 @@ """ -import sys -sys.path.append("./../jupyter-ros") -import jupyros.ros2 as jr2 from ipywidgets import Output from ipycanvas import Canvas -import rclpy -from time import time -## Method to receive keyboard input commands and send a String message to a Subcriber -## It is recommended to use a secondary node to translate your String message to an appropiate msg type +# Method to receive keyboard input commands and send a String message to a Subscriber +# It is recommended to use a secondary node to translate your String message to an appropriate msg type -class key_input: +class KeyInput: - #Initiate values - def __init__(self, node, msg_type, topic, key_bindings = None): + # Initiate values + def __init__(self, node, msg_type, topic, key_bindings=None): # Set default Window size and colors self.width = 400 self.height = 400 - self.color = "blue" - - - ## Initiate values for Ipycanvas to + self.color = "#1E3888" + + # Initiate values for Ipycanvas to self.canvas = Canvas() self.canvas.fill_style = self.color - self.canvas.fill_rect(0, 0, self.width , self.height) + self.canvas.fill_rect(0, 0, self.width, self.height) self.out = Output() self.msg_inst = msg_type() @@ -45,69 +39,58 @@ def __init__(self, node, msg_type, topic, key_bindings = None): self.print_outgoing_msg = True self.canvas.text_align = "center" - - + self.key_bindings = key_bindings self.smallest_size = min(self.width, self.height) - - - #Using the Ros2 Jupyros Publisher module, create - #self.key_in = jr2.Publisher(node, msg_type, topic) - # Method to change the window color def set_color(self, color): self.color = color - - + # Method to change the window width def set_width(self, width): self.width = width # Method to change the window height - def set_height (self, height): + def set_height(self, height): self.height = height - - - def print_outgoing(Var: bool): - self.print_outgoing_msg = Var - def update(self): - self.canvas.fill_rect(0, 0, self.width , self.height) - + def print_outgoing(self, var: bool): + self.print_outgoing_msg = var - + def update(self): + self.canvas.fill_rect(0, 0, self.width, self.height) - # method to display the screen and to receive keyboard inputs - def display(self): + # Method to display the screen and to receive keyboard inputs + def display_inputs(self): self.update() @self.out.capture() def on_keyboard_event(key, shift_key, ctrl_key, meta_key): - if (key): - if(self.print_outgoing_msg): - self.canvas.fill_rect(0, 0, self.width , self.height) - if(str(key) == "ArrowRight"): + if key: + if self.print_outgoing_msg: + self.canvas.fill_rect(0, 0, self.width, self.height) + if str(key) == "ArrowRight": print_key = "⇒" - elif(str(key) == "ArrowDown"): + elif str(key) == "ArrowDown": print_key = "⇓" - elif(str(key) == "ArrowLeft"): + elif str(key) == "ArrowLeft": print_key = "⇐" - elif(str(key) == "ArrowUp"): + elif str(key) == "ArrowUp": print_key = "⇑" else: print_key = key - if(len(str(print_key))>2): + if len(str(print_key)) > 2: factor = 5.5 else: factor = 3 - self.canvas.fill_style = "red" + self.canvas.fill_style = "#E3DFFF" self.font_size = self.smallest_size/factor self.canvas.font = "{}px sans-serif".format(self.font_size) - self.canvas.fill_text(print_key,self.width/2, self.height/2+self.font_size/3) - self.canvas.fill_style = "blue" + self.canvas.fill_text(print_key, self.width/2, self.height/2+self.font_size/3) + self.canvas.fill_style = self.color self.msg_inst.data = str(key) self.__publisher.publish(self.msg_inst) @@ -115,13 +98,3 @@ def on_keyboard_event(key, shift_key, ctrl_key, meta_key): self.canvas.on_key_down(on_keyboard_event) display(self.canvas) display(self.out) - - - - - - - - - - From d19dbe2ba4556b9380d54c5580eb53dcec760bdc Mon Sep 17 00:00:00 2001 From: Isabel Paredes Date: Tue, 23 Aug 2022 12:19:54 +0200 Subject: [PATCH 2/3] Improve canvas update The canvas is cleared before new canvases are drawn on top. Changing the canvas properties also automatically updates the canvas. --- jupyros/ros2/key_input.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/jupyros/ros2/key_input.py b/jupyros/ros2/key_input.py index c1ab28f..1b646d5 100644 --- a/jupyros/ros2/key_input.py +++ b/jupyros/ros2/key_input.py @@ -22,12 +22,13 @@ class KeyInput: # Initiate values def __init__(self, node, msg_type, topic, key_bindings=None): - # Set default Window size and colors + # Set default window size and colors self.width = 400 self.height = 400 self.color = "#1E3888" + self.font_color = "#E3DFFF" - # Initiate values for Ipycanvas to + # Initiate values for ipycanvas to self.canvas = Canvas() self.canvas.fill_style = self.color self.canvas.fill_rect(0, 0, self.width, self.height) @@ -39,27 +40,32 @@ def __init__(self, node, msg_type, topic, key_bindings=None): self.print_outgoing_msg = True self.canvas.text_align = "center" - self.key_bindings = key_bindings - self.smallest_size = min(self.width, self.height) # Method to change the window color def set_color(self, color): self.color = color + self.canvas.fill_style = self.color + self.update() # Method to change the window width def set_width(self, width): self.width = width + self.smallest_size = min(self.width, self.height) + self.update() # Method to change the window height def set_height(self, height): self.height = height + self.smallest_size = min(self.width, self.height) + self.update() def print_outgoing(self, var: bool): self.print_outgoing_msg = var def update(self): + self.canvas.clear() self.canvas.fill_rect(0, 0, self.width, self.height) # Method to display the screen and to receive keyboard inputs @@ -86,7 +92,8 @@ def on_keyboard_event(key, shift_key, ctrl_key, meta_key): factor = 5.5 else: factor = 3 - self.canvas.fill_style = "#E3DFFF" + + self.canvas.fill_style = self.font_color self.font_size = self.smallest_size/factor self.canvas.font = "{}px sans-serif".format(self.font_size) self.canvas.fill_text(print_key, self.width/2, self.height/2+self.font_size/3) From 95d2ce0a44d11b4ae8a07d86348238db3c594f2f Mon Sep 17 00:00:00 2001 From: Isabel Paredes Date: Tue, 23 Aug 2022 12:22:11 +0200 Subject: [PATCH 3/3] Clean notebook --- notebooks/ROS2_Keyboard_Input.ipynb | 128 +++++++--------------------- 1 file changed, 33 insertions(+), 95 deletions(-) diff --git a/notebooks/ROS2_Keyboard_Input.ipynb b/notebooks/ROS2_Keyboard_Input.ipynb index 32d9cdd..2529939 100644 --- a/notebooks/ROS2_Keyboard_Input.ipynb +++ b/notebooks/ROS2_Keyboard_Input.ipynb @@ -1,39 +1,43 @@ { "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# ROS2: Keyboard Inputs\n", + "---\n", + "\n", + "### Requirements\n", + "- `ros-humble-rclpy`\n" + ] + }, { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ - "## Relative pathing to the Jupyros module (jupyter-ros/jupyros), due to difficulty with with development install\n", - "## Remove at PR if Dev Install successful \n", - "import sys\n", - "sys.path.append(\"./../\")\n", - "##\n", "import rclpy as rp\n", - "import jupyros.ros2 as jr2\n", - "from geometry_msgs.msg import Pose, Point\n", + "import jupyros as jr2\n", "from std_msgs.msg import String" ] }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Initialize ROS communications for a given context\n", - "if(rp.ok() == True):\n", + "if rp.ok():\n", " print(\"Rclpy already initiated\")\n", "else:\n", - " rp.init()\n", - " \n" + " rp.init()" ] }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -42,7 +46,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -50,111 +54,45 @@ ] }, { - "cell_type": "code", - "execution_count": 5, + "cell_type": "markdown", "metadata": {}, - "outputs": [], "source": [ - "def cb(msg):\n", - " print(\"This is the data\", msg.data)" + "### Keyboard Input Widget" ] }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ - "key_send = jr2.key_input(key_node, String, '/pose_stream')" + "key_send = jr2.KeyInput(key_node, String, '/keyboard_stream')\n", + "key_send.display_inputs()" ] }, { "cell_type": "code", - "execution_count": 7, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ - "key_send.set_height(400)\n", - "key_send.set_width(400)" + "key_send.set_height(50)\n", + "key_send.set_width(200)\n", + "key_send.set_color(\"black\")" ] }, { "cell_type": "code", - "execution_count": 8, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "f5710a7174f74a3bb4388375d3d0a84f", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "Canvas()" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "8c79f041075144de811d02cad33c5e4f", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "Output()" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ + "def cb(msg):\n", + " return msg.data\n", "\n", - "key_send.display()\n" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "7cb8fbf5dc0f4188ae733724622ecd97", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "VBox(children=(HBox(children=(Button(description='Start', style=ButtonStyle()), Button(description='Stop', sty…" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "sub = jr2.Subscriber(key_node, String, '/pose_stream', cb, print_incoming_msg=True)\n", + "sub = jr2.Subscriber(key_node, String, '/keyboard_stream', cb, print_incoming_msg=True)\n", "sub.display()" ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] } ], "metadata": { @@ -173,7 +111,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.8.10" + "version": "3.9.13" } }, "nbformat": 4,