From ac85bfe50b4a4437d6473e293dbae0d12b423daf Mon Sep 17 00:00:00 2001 From: DenisaCG Date: Tue, 31 Jan 2023 22:04:24 +0100 Subject: [PATCH 1/3] Control the LegoBoost with Game Controller --- examples/controller.ipynb | 189 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 189 insertions(+) create mode 100644 examples/controller.ipynb diff --git a/examples/controller.ipynb b/examples/controller.ipynb new file mode 100644 index 0000000..47a1a6d --- /dev/null +++ b/examples/controller.ipynb @@ -0,0 +1,189 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 2, + "id": "5c2db71d-d832-4ab3-8026-5ba8529032ae", + "metadata": {}, + "outputs": [], + "source": [ + "# uncomment the line below to download ipywidgets, if you don't have it\n", + "# !pip install ipywidgets" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "1f5760ec-3540-461a-84ed-359bac5a7db4", + "metadata": {}, + "outputs": [], + "source": [ + "import ipywidgets as wid\n", + "from pylgbst.hub import MoveHub\n", + "from pylgbst import get_connection_bleak\n", + "import time\n", + "import random" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "58d8a6f4-e17a-4a87-beb3-23d1e683015c", + "metadata": {}, + "outputs": [], + "source": [ + "# initializing the controller\n", + "gamepad = wid.Controller()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5f9947e7-b4a9-42fb-aff9-e8fb2060da5f", + "metadata": {}, + "outputs": [], + "source": [ + "# connecting to the MoveHub using its individual Bluetooth address \n", + "conn = get_connection_bleak(hub_mac='00:16:53:C3:C2:4F', hub_name=MoveHub.DEFAULT_NAME)\n", + "hub = MoveHub(conn)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8fb85790-a43c-4b8c-b609-fb0caf7b5dea", + "metadata": {}, + "outputs": [], + "source": [ + "def on_sent(data):\n", + " if gamepad.connected:\n", + " # moving forward (right joystick)\n", + " if data['owner'].axes[3].value < 0:\n", + " hub.motor_AB.timed(1, 0.1, 0.1)\n", + " \n", + " # moving backwards (right joystick)\n", + " if data['owner'].axes[3].value > 0:\n", + " hub.motor_AB.timed(1, -0.1, -0.1)\n", + " \n", + " # moving to the right (right joystick)\n", + " if data['owner'].axes[2].value < 0:\n", + " hub.motor_A.angled(540, 1)\n", + " \n", + " # moving to the left (right joystick)\n", + " if data['owner'].axes[2].value > 0:\n", + " hub.motor_B.angled(540, 1)\n", + " \n", + " # speeding forward (R2 button)\n", + " if data['owner'].button[7].value:\n", + " hub.motor_AB.timed(1, 2, 2)\n", + " \n", + " # stoping the motors fully (R1 button)\n", + " if data['owner'].button[5].value:\n", + " hub.motor_external.stop()\n", + " \n", + " # changing led color (select button)\n", + " if data['owner'].button[8].value:\n", + " # randomly generated color\n", + " color = (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))\n", + " hub.led.set_color(color)\n", + " \n", + " # move in a square (B button)\n", + " if data['owner'].button[0].value:\n", + " for count in range(4):\n", + " hub.motor_AB.timed(2, 0.2, 0.2)\n", + " hub.motor_A.angled(540, 1)\n", + " \n", + " # move in a circle (A button)\n", + " if data['owner'].button[1].value:\n", + " for count in range(4):\n", + " hub.motor_AB.timed(1.1, (-0.5), (-0.9))\n", + " \n", + " # rotate 360° (Y button)\n", + " if data['owner'].button[2].value:\n", + " hub.motor_A.timed(1.7, 1)\n", + " \n", + " # distance detection (up arrow) \n", + " if data['owner'].button[12].value:\n", + " def callback(distance):\n", + " print(\"Distance: %s\" % (distance))\n", + " \n", + " hub.vision_sensor.subscribe(callback, mode=VisionSensor.DISTANCE_INCHES)\n", + " time.sleep(2)# play with sensor while it waits\n", + " hub.vision_sensor.unsubscribe(callback)\n", + " \n", + " # color detection (left arrow) \n", + " if data['owner'].button[14].value:\n", + " def callback(color):\n", + " print(\"Color: %s\" % (color))\n", + " \n", + " hub.vision_sensor.subscribe(callback, mode=VisionSensor.COLOR_INDEX)\n", + " time.sleep(2)# play with sensor while it waits\n", + " hub.vision_sensor.unsubscribe(callback)\n", + " \n", + " # detect color and distance (down arrow)\n", + " if data['owner'].button[13].value:\n", + " def callback(color, distance):\n", + " print(\"Color: %s / Distance: %s\" % (color, distance))\n", + " \n", + " hub.vision_sensor.subscribe(callback, mode=VisionSensor.COLOR_DISTANCE_FLOAT)\n", + " time.sleep(2)# play with sensor while it waits\n", + " hub.vision_sensor.unsubscribe(callback)\n", + " \n", + " # detect 3-axis position (right arrow)\n", + " if data['owner'].button[15].value:\n", + " def callback(roll, pitch, yaw):\n", + " print(\"Roll: %s / Pitch: %s / Yaw: %s\" % (roll, pitch, yaw))\n", + " \n", + " hub.tilt_sensor.subscribe(callback, mode=TiltSensor.MODE_2AXIS_ACCEL)\n", + " time.sleep(2)# play with sensor while it waits\n", + " hub.tilt_sensor.unsubscribe(callback)\n", + "\n", + " # second joystick for controlling head position? (experiment)\n", + " \n", + "gamepad.observe(on_sent)\n", + "gamepad\n", + "# buttons are corresponding to a 8BitDo Controller" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "926e52ba-251f-4495-8859-9ad61f2d90b7", + "metadata": {}, + "outputs": [], + "source": [ + "# disconnecting from the MoveHub\n", + "hub.disconnect()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4b34a619-d1d1-4a95-a44d-dc09a97f5aaf", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.5" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From dcec118ca7ae5b093c48a783abb96236c83ae570 Mon Sep 17 00:00:00 2001 From: DenisaCG Date: Wed, 8 Feb 2023 00:33:00 +0100 Subject: [PATCH 2/3] additional functionalities and fixed errors --- examples/controller.ipynb | 159 +++++++++++++++++++++++++++----------- 1 file changed, 116 insertions(+), 43 deletions(-) diff --git a/examples/controller.ipynb b/examples/controller.ipynb index 47a1a6d..2f35109 100644 --- a/examples/controller.ipynb +++ b/examples/controller.ipynb @@ -1,47 +1,68 @@ { "cells": [ + { + "cell_type": "markdown", + "id": "21a70f02-65b0-4d1c-8023-c95188dd4d0c", + "metadata": {}, + "source": [ + "## Control the Lego Boost using a Game Controller" + ] + }, + { + "cell_type": "markdown", + "id": "b778cc3a-4bd6-48fd-94c5-456652ec7de6", + "metadata": {}, + "source": [ + "Run the cells below to import the needed libraries, as well as initialize the controller. Buttons are corresponding to a 8BitDo controller." + ] + }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 1, "id": "5c2db71d-d832-4ab3-8026-5ba8529032ae", "metadata": {}, "outputs": [], "source": [ - "# uncomment the line below to download ipywidgets, if you don't have it\n", + "# uncomment the line below to download ipywidgets\n", "# !pip install ipywidgets" ] }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 2, "id": "1f5760ec-3540-461a-84ed-359bac5a7db4", "metadata": {}, "outputs": [], "source": [ "import ipywidgets as wid\n", - "from pylgbst.hub import MoveHub\n", + "from pylgbst.hub import MoveHub, VisionSensor, TiltSensor\n", "from pylgbst import get_connection_bleak\n", "import time\n", "import random" ] }, { - "cell_type": "code", - "execution_count": 4, - "id": "58d8a6f4-e17a-4a87-beb3-23d1e683015c", + "cell_type": "markdown", + "id": "e50a51b4-686a-40ea-b9a2-62ad13067a55", "metadata": {}, - "outputs": [], "source": [ - "# initializing the controller\n", - "gamepad = wid.Controller()" + "Make sure to add the Bluetooth address of your MoveHub, which can be found in settings. Before running the cell below, press the button on your MoveHub such that the LED is flashing, this means its looking for a connection. Once the connection is stable, the LED will turn blue." ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "id": "5f9947e7-b4a9-42fb-aff9-e8fb2060da5f", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Have no dedicated class for peripheral type 0x42 (UNKNOWN) on port 0x46\n" + ] + } + ], "source": [ "# connecting to the MoveHub using its individual Bluetooth address \n", "conn = get_connection_bleak(hub_mac='00:16:53:C3:C2:4F', hub_name=MoveHub.DEFAULT_NAME)\n", @@ -50,10 +71,37 @@ }, { "cell_type": "code", - "execution_count": null, - "id": "8fb85790-a43c-4b8c-b609-fb0caf7b5dea", + "execution_count": 4, + "id": "58d8a6f4-e17a-4a87-beb3-23d1e683015c", "metadata": {}, "outputs": [], + "source": [ + "# initializing the controller\n", + "gamepad = wid.Controller()" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "8fb85790-a43c-4b8c-b609-fb0caf7b5dea", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "43816f3d07814309874f31798f4b06e1", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Controller(axes=(Axis(value=0.0), Axis(value=0.0), Axis(value=0.0), Axis(value=0.0)), buttons=(Button(value=0.…" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "def on_sent(data):\n", " if gamepad.connected:\n", @@ -66,44 +114,49 @@ " hub.motor_AB.timed(1, -0.1, -0.1)\n", " \n", " # moving to the right (right joystick)\n", - " if data['owner'].axes[2].value < 0:\n", - " hub.motor_A.angled(540, 1)\n", + " if data['owner'].axes[0].value < 0:\n", + " hub.motor_B.timed(1, 0.1)\n", " \n", " # moving to the left (right joystick)\n", - " if data['owner'].axes[2].value > 0:\n", - " hub.motor_B.angled(540, 1)\n", + " if data['owner'].axes[0].value > 0:\n", + " hub.motor_A.timed(1, 0.1)\n", " \n", " # speeding forward (R2 button)\n", - " if data['owner'].button[7].value:\n", - " hub.motor_AB.timed(1, 2, 2)\n", + " if data['owner'].buttons[7].value:\n", + " hub.motor_AB.timed(1, 1, 1)\n", " \n", - " # stoping the motors fully (R1 button)\n", - " if data['owner'].button[5].value:\n", + " # stoping the motors fully (L2 button)\n", + " if data['owner'].buttons[6].value:\n", " hub.motor_external.stop()\n", " \n", " # changing led color (select button)\n", - " if data['owner'].button[8].value:\n", + " if data['owner'].buttons[8].value:\n", " # randomly generated color\n", " color = (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))\n", " hub.led.set_color(color)\n", " \n", " # move in a square (B button)\n", - " if data['owner'].button[0].value:\n", - " for count in range(4):\n", - " hub.motor_AB.timed(2, 0.2, 0.2)\n", + " if data['owner'].buttons[0].value:\n", + " for count in range(2):\n", + " hub.motor_AB.timed(1, 0.1, 0.1)\n", " hub.motor_A.angled(540, 1)\n", " \n", " # move in a circle (A button)\n", - " if data['owner'].button[1].value:\n", - " for count in range(4):\n", - " hub.motor_AB.timed(1.1, (-0.5), (-0.9))\n", + " if data['owner'].buttons[1].value:\n", + " for count in range(2):\n", + " hub.motor_AB.timed(1, 0.1, 0.5)\n", " \n", " # rotate 360° (Y button)\n", - " if data['owner'].button[2].value:\n", - " hub.motor_A.timed(1.7, 1)\n", + " if data['owner'].buttons[2].value:\n", + " hub.motor_A.timed(1.5, 1)\n", + " \n", + " # shoot arrow (X button)\n", + " if data['owner'].buttons[3].value:\n", + " hub.port_D.timed(0.3, 0.5)\n", + " hub.port_D.timed(0.3, -0.4)\n", " \n", " # distance detection (up arrow) \n", - " if data['owner'].button[12].value:\n", + " if data['owner'].buttons[12].value:\n", " def callback(distance):\n", " print(\"Distance: %s\" % (distance))\n", " \n", @@ -112,7 +165,7 @@ " hub.vision_sensor.unsubscribe(callback)\n", " \n", " # color detection (left arrow) \n", - " if data['owner'].button[14].value:\n", + " if data['owner'].buttons[14].value:\n", " def callback(color):\n", " print(\"Color: %s\" % (color))\n", " \n", @@ -121,7 +174,7 @@ " hub.vision_sensor.unsubscribe(callback)\n", " \n", " # detect color and distance (down arrow)\n", - " if data['owner'].button[13].value:\n", + " if data['owner'].buttons[13].value:\n", " def callback(color, distance):\n", " print(\"Color: %s / Distance: %s\" % (color, distance))\n", " \n", @@ -130,36 +183,56 @@ " hub.vision_sensor.unsubscribe(callback)\n", " \n", " # detect 3-axis position (right arrow)\n", - " if data['owner'].button[15].value:\n", + " if data['owner'].buttons[15].value:\n", " def callback(roll, pitch, yaw):\n", " print(\"Roll: %s / Pitch: %s / Yaw: %s\" % (roll, pitch, yaw))\n", " \n", - " hub.tilt_sensor.subscribe(callback, mode=TiltSensor.MODE_2AXIS_ACCEL)\n", + " hub.tilt_sensor.subscribe(callback, mode=TiltSensor.MODE_3AXIS_ACCEL)\n", " time.sleep(2)# play with sensor while it waits\n", " hub.tilt_sensor.unsubscribe(callback)\n", "\n", - " # second joystick for controlling head position? (experiment)\n", + " # turn head to left (L1 button)\n", + " if data['owner'].buttons[4].value:\n", + " hub.port_D.timed(0.15, 0.4)\n", " \n", + " # turn head to the right (R1 button)\n", + " if data['owner'].buttons[5].value:\n", + " hub.port_D.timed(0.15, -0.4)\n", + " \n", "gamepad.observe(on_sent)\n", - "gamepad\n", - "# buttons are corresponding to a 8BitDo Controller" + "gamepad" + ] + }, + { + "cell_type": "markdown", + "id": "62a0684a-1a0b-4899-8708-7a9a7ae23132", + "metadata": {}, + "source": [ + "Run the cell below to disconnect from the MoveHub. " ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 6, "id": "926e52ba-251f-4495-8859-9ad61f2d90b7", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Hub disconnects\n" + ] + } + ], "source": [ - "# disconnecting from the MoveHub\n", "hub.disconnect()" ] }, { "cell_type": "code", "execution_count": null, - "id": "4b34a619-d1d1-4a95-a44d-dc09a97f5aaf", + "id": "1e57f611-dd04-474b-93d7-222058c6da26", "metadata": {}, "outputs": [], "source": [] From 5c6de12bc70e251a31fe586dfeb9f4b93b98c925 Mon Sep 17 00:00:00 2001 From: DenisaCG Date: Mon, 20 Feb 2023 21:45:55 +0100 Subject: [PATCH 3/3] change lint and prettier configuration for CHANGELOG.md --- .eslintignore | 3 +++ .prettierignore | 3 +++ 2 files changed, 6 insertions(+) diff --git a/.eslintignore b/.eslintignore index a26b71a..e5c5bf1 100644 --- a/.eslintignore +++ b/.eslintignore @@ -11,3 +11,6 @@ examples .eslintignore .eslintrc.js .gitignore + +.github +CHANGELOG.md diff --git a/.prettierignore b/.prettierignore index 6d1c10b..fc7a99e 100644 --- a/.prettierignore +++ b/.prettierignore @@ -3,3 +3,6 @@ node_modules **/lib **/package.json jupyterlab_lego_boost + +.github +CHANGELOG.md \ No newline at end of file