From 506a74aca758eb7d4febf524dab18213c459f5af Mon Sep 17 00:00:00 2001 From: n-akram <31505221+n-akram@users.noreply.github.com> Date: Sat, 30 Sep 2023 18:28:36 +0200 Subject: [PATCH] Example for collision risk assessment - Incomplete --- SafeDrones/core/SafeDrones.py | 14 ++- example/SafeDrone-demo-2.ipynb | 177 +++++++++++++++++++++++++++++++++ 2 files changed, 187 insertions(+), 4 deletions(-) create mode 100644 example/SafeDrone-demo-2.ipynb diff --git a/SafeDrones/core/SafeDrones.py b/SafeDrones/core/SafeDrones.py index 484c838..8926146 100644 --- a/SafeDrones/core/SafeDrones.py +++ b/SafeDrones/core/SafeDrones.py @@ -32,13 +32,14 @@ def __init__(self): self.danger_threshold = None self.collision_threshold = None - + self.GPS_Lambda = None + self.Set_Variables() def Set_Variables(self, MotorStatus=[1,1,1,1,1,1], Motors_Configuration='PNPNPN',\ Motors_Lambda = 0.001, Batt_Lambda = 0.001, alpha = 0.008, beta = 0.007, \ Battery_degradation_rate = 0.0064, BatteryLevel=80, MTTFref=400, \ - Tr=30, Ta=50, u=1,b=1, time=100, ): + Tr=30, Ta=50, u=1,b=1, time=100, danger_threshold=2, collision_threshold=0, GPS_Lambda=0.001): #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Version : 1.0.0 % # Description : set variables used in the program % @@ -66,6 +67,11 @@ def Set_Variables(self, MotorStatus=[1,1,1,1,1,1], Motors_Configuration='PNPNPN' # Mission Time self.time = time + + #Collision related + self.danger_threshold = danger_threshold + self.collision_threshold = collision_threshold + self.GPS_Lambda = GPS_Lambda def Motor_Failure_Risk_Calc(self, MotorStatus=None, Motors_Configuration=None, Motors_Lambda=None, time=None): @@ -624,9 +630,9 @@ def calculate_collision_risk(self, uav_1_trajectory, uav_2_trajectory): # self. for point_1, point_2 in zip(uav_1_trajectory, uav_2_trajectory): distance = np.linalg.norm(np.array(point_1) - np.array(point_2)) - if distance < collision_threshold: + if distance < self.collision_threshold: collision_zone_count += 1 - elif distance < danger_threshold: + elif distance < self.danger_threshold: danger_zone_count += 1 danger_zone_risk = danger_zone_count / len(uav_1_trajectory) diff --git a/example/SafeDrone-demo-2.ipynb b/example/SafeDrone-demo-2.ipynb new file mode 100644 index 0000000..a759d3b --- /dev/null +++ b/example/SafeDrone-demo-2.ipynb @@ -0,0 +1,177 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Using SafeDrone for collision risk assessment\n", + "\n", + "SafeDrone can be used for risk of collision of the drones. It takes the trajectory of the drones as an input, and calculates the risk of collision. \n", + "\n", + "The drone consists of three main electrical components that are essential for its operation.\n", + "1. Motor (Rotor)\n", + "2. Battery\n", + "3. Onboard chip\n", + "\n", + "In the following, we show an example usage of drone collision risk assessment. " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import os\n", + "\n", + "import inspect\n", + "\n", + "from IPython.display import Markdown as md\n", + "\n", + "from sys import platform\n", + "\n", + "if platform == \"linux\" or platform == \"linux2\":\n", + " currentdir = os.path.dirname(os.path.realpath(inspect.getfile(inspect.currentframe())))\n", + " parentdir = os.path.dirname(currentdir)\n", + " sys.path.insert(0, parentdir)\n", + "elif platform == \"win32\":\n", + " # in Windows, the first path entry contains the directory where the notebook is\n", + " sys.path.insert(0, os.path.dirname(sys.path[0]))\n", + "\n", + "from SafeDrones.core.SafeDrones import SafeDrones" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "eval = SafeDrones()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Initialize the variables . . . .\n", + "Use $5$ as collision threshold, and $10$ as danger threshold. GPS lambda can be used the default ($0.001$)." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "eval.Set_Variables(collision_threshold=5, danger_threshold=10, GPS_Lambda=0.001)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Sample trajectories . . . . " + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "traj_1 = np.array([1, 2, 3, 4, 5, 6])\n", + "traj_2 = np.array([1, 2, 3, 4, 5, 6])" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(0.0, 1.0)" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "risk = eval.calculate_collision_risk(traj_1, traj_2)\n", + "risk" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Check the risk of GPS failure . . . . " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## INCOMPLETE . . . ." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "ename": "AttributeError", + "evalue": "'SafeDrones' object has no attribute 'SatStatus'", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mAttributeError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32mc:\\AKRAM-Local\\github\\SafeDrones\\example\\SafeDrone-demo-2.ipynb Cell 12\u001b[0m line \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[1;32m----> 1\u001b[0m gps_risk \u001b[39m=\u001b[39m \u001b[39meval\u001b[39;49m\u001b[39m.\u001b[39;49mGPS_Failure_Risk_Calc()\n", + "File \u001b[1;32mc:\\AKRAM-Local\\github\\SafeDrones\\SafeDrones\\core\\SafeDrones.py:604\u001b[0m, in \u001b[0;36mSafeDrones.GPS_Failure_Risk_Calc\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m 592\u001b[0m t \u001b[39m=\u001b[39m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mtime\n\u001b[0;32m 594\u001b[0m M \u001b[39m=\u001b[39m np\u001b[39m.\u001b[39marray([[\u001b[39m-\u001b[39m\u001b[39m14\u001b[39m\u001b[39m*\u001b[39mL, \u001b[39m0\u001b[39m, \u001b[39m0\u001b[39m, \u001b[39m0\u001b[39m, \u001b[39m0\u001b[39m, \u001b[39m0\u001b[39m, \u001b[39m0\u001b[39m, \u001b[39m0\u001b[39m, \u001b[39m0\u001b[39m],\n\u001b[0;32m 595\u001b[0m [ \u001b[39m14\u001b[39m\u001b[39m*\u001b[39mL, \u001b[39m-\u001b[39m\u001b[39m13\u001b[39m\u001b[39m*\u001b[39mL, \u001b[39m0\u001b[39m, \u001b[39m0\u001b[39m, \u001b[39m0\u001b[39m, \u001b[39m0\u001b[39m, \u001b[39m0\u001b[39m, \u001b[39m0\u001b[39m, \u001b[39m0\u001b[39m],\n\u001b[0;32m 596\u001b[0m [ \u001b[39m0\u001b[39m, \u001b[39m13\u001b[39m\u001b[39m*\u001b[39mL, \u001b[39m-\u001b[39m\u001b[39m12\u001b[39m\u001b[39m*\u001b[39mL, \u001b[39m0\u001b[39m, \u001b[39m0\u001b[39m, \u001b[39m0\u001b[39m, \u001b[39m0\u001b[39m, \u001b[39m0\u001b[39m, \u001b[39m0\u001b[39m],\n\u001b[1;32m (...)\u001b[0m\n\u001b[0;32m 601\u001b[0m [ \u001b[39m0\u001b[39m, \u001b[39m0\u001b[39m, \u001b[39m0\u001b[39m, \u001b[39m0\u001b[39m, \u001b[39m0\u001b[39m, \u001b[39m0\u001b[39m, \u001b[39m8\u001b[39m\u001b[39m*\u001b[39mL, \u001b[39m-\u001b[39m\u001b[39m7\u001b[39m\u001b[39m*\u001b[39mL, \u001b[39m0\u001b[39m],\n\u001b[0;32m 602\u001b[0m [ \u001b[39m0\u001b[39m, \u001b[39m0\u001b[39m, \u001b[39m0\u001b[39m, \u001b[39m0\u001b[39m, \u001b[39m0\u001b[39m, \u001b[39m0\u001b[39m, \u001b[39m0\u001b[39m, \u001b[39m7\u001b[39m\u001b[39m*\u001b[39mL, \u001b[39m0\u001b[39m]])\n\u001b[1;32m--> 604\u001b[0m P \u001b[39m=\u001b[39m np\u001b[39m.\u001b[39mdot(sym\u001b[39m.\u001b[39mexp(M\u001b[39m*\u001b[39mt), \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49mSatStatus)\n\u001b[0;32m 606\u001b[0m P_Fail \u001b[39m=\u001b[39m P[\u001b[39m-\u001b[39m\u001b[39m1\u001b[39m]\n\u001b[0;32m 608\u001b[0m N \u001b[39m=\u001b[39m np\u001b[39m.\u001b[39marray([[\u001b[39m-\u001b[39m\u001b[39m14\u001b[39m\u001b[39m*\u001b[39mL, \u001b[39m0\u001b[39m, \u001b[39m0\u001b[39m, \u001b[39m0\u001b[39m, \u001b[39m0\u001b[39m, \u001b[39m0\u001b[39m, \u001b[39m0\u001b[39m, \u001b[39m0\u001b[39m],\n\u001b[0;32m 609\u001b[0m [ \u001b[39m14\u001b[39m\u001b[39m*\u001b[39mL, \u001b[39m-\u001b[39m\u001b[39m13\u001b[39m\u001b[39m*\u001b[39mL, \u001b[39m0\u001b[39m, \u001b[39m0\u001b[39m, \u001b[39m0\u001b[39m, \u001b[39m0\u001b[39m, \u001b[39m0\u001b[39m, \u001b[39m0\u001b[39m],\n\u001b[0;32m 610\u001b[0m [ \u001b[39m0\u001b[39m, \u001b[39m13\u001b[39m\u001b[39m*\u001b[39mL, \u001b[39m-\u001b[39m\u001b[39m12\u001b[39m\u001b[39m*\u001b[39mL, \u001b[39m0\u001b[39m, \u001b[39m0\u001b[39m, \u001b[39m0\u001b[39m, \u001b[39m0\u001b[39m, \u001b[39m0\u001b[39m],\n\u001b[1;32m (...)\u001b[0m\n\u001b[0;32m 614\u001b[0m [ \u001b[39m0\u001b[39m, \u001b[39m0\u001b[39m, \u001b[39m0\u001b[39m, \u001b[39m0\u001b[39m, \u001b[39m0\u001b[39m, \u001b[39m9\u001b[39m\u001b[39m*\u001b[39mL, \u001b[39m-\u001b[39m\u001b[39m8\u001b[39m\u001b[39m*\u001b[39mL, \u001b[39m0\u001b[39m],\n\u001b[0;32m 615\u001b[0m [ \u001b[39m0\u001b[39m, \u001b[39m0\u001b[39m, \u001b[39m0\u001b[39m, \u001b[39m0\u001b[39m, \u001b[39m0\u001b[39m, \u001b[39m0\u001b[39m, \u001b[39m8\u001b[39m\u001b[39m*\u001b[39mL, \u001b[39m-\u001b[39m\u001b[39m7\u001b[39m\u001b[39m*\u001b[39mL]])\n", + "\u001b[1;31mAttributeError\u001b[0m: 'SafeDrones' object has no attribute 'SatStatus'" + ] + } + ], + "source": [ + "gps_risk = eval.GPS_Failure_Risk_Calc()" + ] + } + ], + "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.8.13" + }, + "orig_nbformat": 4 + }, + "nbformat": 4, + "nbformat_minor": 2 +}