├── hack ├── bootc │ ├── json │ │ ├── output │ │ │ └── qcow2 │ │ │ │ └── README │ │ ├── config.toml │ │ └── space-grade-linux-distro.json │ ├── tools │ │ ├── space-list-active-vms │ │ ├── space-list-all-vms │ │ ├── space-console-to-vm │ │ ├── space-delete-vms │ │ └── space-generate-and-run-distro │ └── README.md └── README.md ├── APIs ├── python │ ├── Rocket_Lauch_Simulator │ │ ├── .gitignore │ │ ├── rocket_launcher │ │ │ ├── __pycache__ │ │ │ │ └── __init__.cpython-313.pyc │ │ │ ├── spacex.py │ │ │ ├── nasa.py │ │ │ ├── boeing.py │ │ │ ├── blue_origin.py │ │ │ ├── lockheed_martin.py │ │ │ └── __init__.py │ │ ├── examples │ │ │ ├── lockheed_martin │ │ │ ├── spacex │ │ │ ├── nasa │ │ │ ├── boeing │ │ │ └── blue_origin │ │ ├── README.md │ │ └── setup.py │ ├── Autonomous_Drones │ │ ├── requirements.txt │ │ ├── pics │ │ │ ├── 01.jpg │ │ │ └── 02.jpg │ │ ├── Parrot │ │ │ └── anafi │ │ │ │ └── autonomous_parrot_anafi │ │ ├── README.md │ │ └── dji │ │ │ └── tello │ │ │ └── autonomous_drones │ ├── Cameras │ │ └── IntelRealSense │ │ │ ├── 435i │ │ │ ├── requirements.txt │ │ │ └── __init__.py │ │ │ └── README.md │ ├── Robotic_Arms │ │ └── waveshare │ │ │ ├── __init__.py │ │ │ └── armcontroller.py │ ├── Unmanned_Ground_Vehicles │ │ └── waveshare │ │ │ ├── __init__.py │ │ │ └── ugvcontroller.py │ ├── ROS2_Rocket_Launch_Simulator │ │ ├── setup.py │ │ └── __init__.py │ └── Moon │ │ └── __ini__.py └── C++ │ └── Autonomous_Drones │ └── dji │ └── tello │ └── README.md ├── src ├── engines │ ├── .gitignore │ ├── README.md │ ├── example-create-33-engine-from-template-image-and-payload │ └── Containerfile-template-image-for-rocket-components-or-services ├── crew_espace_system │ ├── run │ └── Containerfile-template-image-for-rocket-components-or-services ├── life_support_system │ ├── run │ └── Containerfile-template-image-for-rocket-components-or-services ├── heat_shield_protection │ ├── run │ └── Containerfile-template-image-for-rocket-components-or-services ├── flight_termination_system │ ├── run │ └── Containerfile-template-image-for-rocket-components-or-services ├── run_all ├── Containerfile └── README.md ├── pics └── model_rockets │ ├── Estes_Saturn_V.jpg │ ├── RecoveryWadding.jpg │ ├── Blue_Origin_Shepard_2198.jpg │ ├── Space_Shuttle_Model_Rocket.jpg │ ├── Estes_2208_Universal_Astrocam.jpg │ ├── Estes_tandem-x_launch_set_30inches.jpg │ ├── Estes_1295_Mean_Machine_Flying_Model_Rocket.jpg │ ├── Estes_2206_NASA_SLS_Flying_Model_Rocket_Kit.jpg │ └── Estes_1441_Journey_Launch_Set_Beginner_Model_Kit.jpg ├── LICENSE └── README.md /hack/bootc/json/output/qcow2/README: -------------------------------------------------------------------------------- 1 | help build system 2 | -------------------------------------------------------------------------------- /APIs/python/Rocket_Lauch_Simulator/.gitignore: -------------------------------------------------------------------------------- 1 | *.egg-info 2 | build/ 3 | -------------------------------------------------------------------------------- /hack/bootc/tools/space-list-active-vms: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | virsh list 4 | -------------------------------------------------------------------------------- /hack/bootc/tools/space-list-all-vms: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | virsh list --all 4 | -------------------------------------------------------------------------------- /src/engines/.gitignore: -------------------------------------------------------------------------------- 1 | Containerfile_engine* 2 | template-Containerfile_engine 3 | -------------------------------------------------------------------------------- /src/engines/README.md: -------------------------------------------------------------------------------- 1 | dnf --installroot /usr/lib/qm/rootfs/ install vim git -y 2 | -------------------------------------------------------------------------------- /APIs/C++/Autonomous_Drones/dji/tello/README.md: -------------------------------------------------------------------------------- 1 | https://github.com/herrnamenlos123/tello 2 | -------------------------------------------------------------------------------- /APIs/python/Autonomous_Drones/requirements.txt: -------------------------------------------------------------------------------- 1 | djitellopy>=2.4 2 | pygame>=2.1.0 3 | logging>=0.5.1.2 4 | -------------------------------------------------------------------------------- /APIs/python/Cameras/IntelRealSense/435i/requirements.txt: -------------------------------------------------------------------------------- 1 | pyrealsense2==2.50.0 2 | numpy>=1.21,<2.0 3 | opencv-python==4.8.1.78 4 | -------------------------------------------------------------------------------- /hack/README.md: -------------------------------------------------------------------------------- 1 | hack dir is a development sandbix. In other word, not official, completely under tests and might never get official. 2 | -------------------------------------------------------------------------------- /pics/model_rockets/Estes_Saturn_V.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/containers/space-grade-linux/HEAD/pics/model_rockets/Estes_Saturn_V.jpg -------------------------------------------------------------------------------- /pics/model_rockets/RecoveryWadding.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/containers/space-grade-linux/HEAD/pics/model_rockets/RecoveryWadding.jpg -------------------------------------------------------------------------------- /APIs/python/Autonomous_Drones/pics/01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/containers/space-grade-linux/HEAD/APIs/python/Autonomous_Drones/pics/01.jpg -------------------------------------------------------------------------------- /APIs/python/Autonomous_Drones/pics/02.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/containers/space-grade-linux/HEAD/APIs/python/Autonomous_Drones/pics/02.jpg -------------------------------------------------------------------------------- /pics/model_rockets/Blue_Origin_Shepard_2198.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/containers/space-grade-linux/HEAD/pics/model_rockets/Blue_Origin_Shepard_2198.jpg -------------------------------------------------------------------------------- /pics/model_rockets/Space_Shuttle_Model_Rocket.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/containers/space-grade-linux/HEAD/pics/model_rockets/Space_Shuttle_Model_Rocket.jpg -------------------------------------------------------------------------------- /pics/model_rockets/Estes_2208_Universal_Astrocam.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/containers/space-grade-linux/HEAD/pics/model_rockets/Estes_2208_Universal_Astrocam.jpg -------------------------------------------------------------------------------- /pics/model_rockets/Estes_tandem-x_launch_set_30inches.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/containers/space-grade-linux/HEAD/pics/model_rockets/Estes_tandem-x_launch_set_30inches.jpg -------------------------------------------------------------------------------- /pics/model_rockets/Estes_1295_Mean_Machine_Flying_Model_Rocket.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/containers/space-grade-linux/HEAD/pics/model_rockets/Estes_1295_Mean_Machine_Flying_Model_Rocket.jpg -------------------------------------------------------------------------------- /pics/model_rockets/Estes_2206_NASA_SLS_Flying_Model_Rocket_Kit.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/containers/space-grade-linux/HEAD/pics/model_rockets/Estes_2206_NASA_SLS_Flying_Model_Rocket_Kit.jpg -------------------------------------------------------------------------------- /src/crew_espace_system/run: -------------------------------------------------------------------------------- 1 | podman run -d --replace --privileged --name crew_espace_system quay.io/qm-images/space-grade-linux-template-image-for-rocket-components-or-services:latest 2 | podman ps 3 | -------------------------------------------------------------------------------- /src/life_support_system/run: -------------------------------------------------------------------------------- 1 | podman run -d --replace --privileged --name life_support_system quay.io/qm-images/space-grade-linux-template-image-for-rocket-components-or-services:latest 2 | podman ps 3 | -------------------------------------------------------------------------------- /pics/model_rockets/Estes_1441_Journey_Launch_Set_Beginner_Model_Kit.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/containers/space-grade-linux/HEAD/pics/model_rockets/Estes_1441_Journey_Launch_Set_Beginner_Model_Kit.jpg -------------------------------------------------------------------------------- /src/heat_shield_protection/run: -------------------------------------------------------------------------------- 1 | podman run -d --replace --privileged --name heat_shield_protection quay.io/qm-images/space-grade-linux-template-image-for-rocket-components-or-services:latest 2 | podman ps 3 | -------------------------------------------------------------------------------- /src/flight_termination_system/run: -------------------------------------------------------------------------------- 1 | podman run -d --replace --privileged --name flight_termination_system quay.io/qm-images/space-grade-linux-template-image-for-rocket-components-or-services:latest 2 | podman ps 3 | -------------------------------------------------------------------------------- /APIs/python/Rocket_Lauch_Simulator/rocket_launcher/__pycache__/__init__.cpython-313.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/containers/space-grade-linux/HEAD/APIs/python/Rocket_Lauch_Simulator/rocket_launcher/__pycache__/__init__.cpython-313.pyc -------------------------------------------------------------------------------- /src/run_all: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [[ $EUID -ne 0 ]]; then 4 | echo "This script must be run as root." >&2 5 | exit 1 6 | fi 7 | 8 | crew_espace_system/run 9 | flight_termination_system/run 10 | heat_shield_protection/run 11 | life_support_system/run 12 | -------------------------------------------------------------------------------- /APIs/python/Cameras/IntelRealSense/README.md: -------------------------------------------------------------------------------- 1 | Intel RealSense cameras are advanced 3D depth-sensing devices that combine stereo vision, infrared (IR) sensors, and sometimes RGB cameras to capture depth and color data in real-time. They are used in robotics, AR/VR, facial recognition, and object detection, enabling machines to perceive and understand their environment. Popular models include D435i (stereo depth) and L515 (LiDAR-based). 2 | -------------------------------------------------------------------------------- /hack/bootc/tools/space-console-to-vm: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Function to print usage information 4 | print_usage() { 5 | echo "Usage: $0 " 6 | echo "Connect to the console of a specified virtual machine." 7 | echo 8 | echo "Arguments:" 9 | echo " The name of the virtual machine to connect to." 10 | exit 1 11 | } 12 | 13 | # Check if an argument is provided 14 | if [[ $# -ne 1 ]]; then 15 | echo "Error: No virtual machine name provided." 16 | print_usage 17 | fi 18 | 19 | # Connect to the virtual machine's console 20 | vm_name="$1" 21 | sudo virsh console "$vm_name" 22 | -------------------------------------------------------------------------------- /hack/bootc/json/config.toml: -------------------------------------------------------------------------------- 1 | [[customizations.user]] 2 | name = "space" 3 | password = "password" 4 | groups = ["wheel"] 5 | 6 | [customizations.installer.kickstart] 7 | contents = """ 8 | text --non-interactive 9 | zerombr 10 | clearpart --all --initlabel --disklabel=gpt 11 | autopart --noswap --type=lvm 12 | network --bootproto=dhcp --device=link --activate --onboot=on 13 | 14 | 15 | # Here's where we reference the container image to install - notice the kickstart 16 | # has no `%packages` section! What's being installed here is a container image. 17 | ostreecontainer --url quay.io/qm-images/space-grade-linux 18 | ostreecontainer --url quay.io/qm-images/space-grade-linux-engine:latest 19 | """ 20 | -------------------------------------------------------------------------------- /APIs/python/Robotic_Arms/waveshare/__init__.py: -------------------------------------------------------------------------------- 1 | # __init__.py 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from .armcontroller import ArmController 16 | -------------------------------------------------------------------------------- /APIs/python/Unmanned_Ground_Vehicles/waveshare/__init__.py: -------------------------------------------------------------------------------- 1 | # __init__.py 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from .ugvcontroller import UGVController 16 | -------------------------------------------------------------------------------- /src/engines/example-create-33-engine-from-template-image-and-payload: -------------------------------------------------------------------------------- 1 | # Number of engines to create 2 | engine_count=33 3 | 4 | podman pull quay.io/qm-images/space-grade-linux-template-image-for-rocket-components-or-services:latest 5 | # Image name 6 | image_name="quay.io/qm-images/space-grade-linux-template-image-for-rocket-components-or-services:latest" 7 | 8 | # Loop to create the engines 9 | for i in $(seq 1 $engine_count); do 10 | podman run --replace -d --privileged --name "spaceship-engine$i" "$image_name" 11 | echo "Spaceship engine $i created." 12 | done 13 | 14 | podman run --replace -d --privileged --name spaceship-payload quay.io/qm-images/space-grade-linux-template-image-for-rocket-components-or-services:latest 15 | 16 | -------------------------------------------------------------------------------- /hack/bootc/tools/space-delete-vms: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Function to display usage 4 | usage() { 5 | echo "Usage: $0 " 6 | echo "Shutdown, destroy, and undefine a virtual machine by name." 7 | exit 1 8 | } 9 | 10 | # Check if an argument is provided 11 | if [ "$#" -ne 1 ]; then 12 | usage 13 | fi 14 | 15 | VM_NAME=$1 16 | 17 | # Perform the actions 18 | echo "Shutting down VM: $VM_NAME" 19 | sudo virsh shutdown "$VM_NAME" 20 | 21 | echo "Destroying VM: $VM_NAME" 22 | sudo virsh destroy "$VM_NAME" 23 | 24 | echo "Undefining VM: $VM_NAME and removing all associated storage" 25 | sudo virsh undefine "$VM_NAME" --remove-all-storage 26 | 27 | echo "Operation completed for VM: $VM_NAME" 28 | 29 | echo -e "\nListing all vms:\n" 30 | sudo virsh list --all 31 | -------------------------------------------------------------------------------- /APIs/python/Rocket_Lauch_Simulator/examples/lockheed_martin: -------------------------------------------------------------------------------- 1 | """ 2 | Module utilizing Lockheed Martin-specific operations for the RocketLaunch simulation. 3 | """ 4 | 5 | from rocket_launcher import RocketLaunch 6 | from rocket_launcher import lockheed_martin 7 | 8 | def main(): 9 | """ 10 | Simulate a Lockheed Martin rocket launch with payload deployment and return operations. 11 | """ 12 | rocket = RocketLaunch("Lockheed Martin Atlas V", "Satellite Payload", "lockheed_martin") 13 | 14 | print("\nStarting Lockheed Martin Rocket Launch Simulation...") 15 | rocket.simulate_launch() 16 | 17 | print("\nExecuting Lockheed Martin Precision Payload Deployment...") 18 | lockheed_martin.lockheed_martin_payload_deployment(rocket) 19 | 20 | print("\nExecuting Lockheed Martin Return and Landing...") 21 | lockheed_martin.lockheed_martin_return_and_landing(rocket) 22 | 23 | if __name__ == "__main__": 24 | main() 25 | -------------------------------------------------------------------------------- /APIs/python/Rocket_Lauch_Simulator/README.md: -------------------------------------------------------------------------------- 1 | ``` 2 | python -m venv ~/pythonvenv/spacegradelinux 3 | source ~/pythonvenv/spacegradelinux 4 | 5 | git clone https://github.com/containers/space-grade-linux.git 6 | cd space-grade-linux/APIs/python/Rocket_Lauch_Simulator 7 | pip install . 8 | cd examples 9 | ./nasa 10 | ``` 11 | 12 | ``` 13 | Starting NASA Rocket Launch Simulation... 14 | 🚀 Starting launch sequence for NASA Mars Mission with payload: Curiosity Rover 🚀 15 | 16 | --- Stage: Pre-Launch Preparations --- 17 | 18 | --- Stage: Ignition and Liftoff --- 19 | 20 | --- Stage: Ascent Stage --- 21 | 22 | --- Stage: Stage Separation --- 23 | 24 | --- Stage: Fairing Separation --- 25 | 26 | --- Stage: Orbital Insertion or Payload Deployment --- 27 | 28 | --- Stage: Stage Reentry and Recovery --- 29 | 30 | --- Stage: Post-Launch Operations --- 31 | 🎉 Launch sequence completed successfully! 🎉 32 | 33 | Executing Curiosity Rover Mission Operations... 34 | 🪐 Curiosity rover entering Martian atmosphere... 35 | 🪂 Deploying parachute for descent... 36 | 🛸 Initiating sky-crane maneuver... 37 | 🪨 Curiosity rover has landed safely on Mars! 38 | 🛰️ Starting surface operations and data collection. 39 | 40 | ``` 41 | -------------------------------------------------------------------------------- /hack/bootc/tools/space-generate-and-run-distro: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | #-it \ 4 | pushd ../distro/json/ 5 | mkdir -p output 6 | sudo podman run \ 7 | -d \ 8 | --rm \ 9 | --name space-grade-linux \ 10 | --replace \ 11 | --privileged \ 12 | --pull=newer \ 13 | --security-opt label=type:unconfined_t \ 14 | -v ./config.toml:/config.toml:ro \ 15 | -v ./output:/output \ 16 | -v /var/lib/containers/storage:/var/lib/containers/storage \ 17 | quay.io/qm-images/space-grade-linux:latest \ 18 | --type qcow2 \ 19 | --local \ 20 | quay.io/centos-bootc/centos-bootc:stream9 21 | 22 | echo -e "\nListing qcow2 image from distro/json/output/qcow2/..." 23 | echo -e "===========================================\n" 24 | ls output/qcow2/ 25 | 26 | sudo virsh destroy space-grade-linux 2> /dev/null 27 | sudo virsh undefine space-grade-linux --remove-all-storage 2> /dev/null 28 | 29 | sudo virt-install \ 30 | --name space-grade-linux \ 31 | --cpu host \ 32 | --vcpus 4 \ 33 | --memory 16096 \ 34 | --import --disk ./output/qcow2/disk.qcow2,format=qcow2,size=20 \ 35 | --os-variant fedora-eln \ 36 | --noautoconsole 37 | 38 | sudo virsh list 39 | popd 40 | -------------------------------------------------------------------------------- /APIs/python/Rocket_Lauch_Simulator/setup.py: -------------------------------------------------------------------------------- 1 | # setup.py 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | from setuptools import setup, find_packages 15 | 16 | setup( 17 | name='rocket_launcher', 18 | version='0.1.0', 19 | description='A rocket launch simulation package.', 20 | author='Douglas Schilling Landgraf, Leonardo Rossetti, Dan Walsh', 21 | author_email='dougsland@redhat.com, lrossett@redhat.com, dwalsh@redhat.com', 22 | license='Apache License 2.0', 23 | packages=find_packages(), 24 | classifiers=[ 25 | 'Programming Language :: Python :: 3', 26 | 'License :: OSI Approved :: Apache Software License', 27 | 'Operating System :: OS Independent', 28 | ], 29 | python_requires='>=3.6', 30 | ) 31 | 32 | -------------------------------------------------------------------------------- /APIs/python/Rocket_Lauch_Simulator/rocket_launcher/spacex.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # Licensed under the Apache License, Version 2.0 (the "License"); 3 | # you may not use this file except in compliance with the License. 4 | # You may obtain a copy of the License at 5 | # 6 | # http://www.apache.org/licenses/LICENSE-2.0 7 | # 8 | # Unless required by applicable law or agreed to in writing, software 9 | # distributed under the License is distributed on an "AS IS" BASIS, 10 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | # See the License for the specific language governing permissions and 12 | # limitations under the License. 13 | 14 | """ 15 | Module containing SpaceX-specific operations for the RocketLaunch simulation. 16 | """ 17 | 18 | def spacex_booster_recovery(rocket): 19 | """ 20 | Special operations for SpaceX booster recovery. 21 | 22 | Parameters: 23 | - rocket (RocketLaunch): Instance of the RocketLaunch class. 24 | """ 25 | rocket.display_message("SpaceX booster initiating controlled descent...", "🛬") 26 | rocket.display_message("Adjusting fins for precise landing maneuver...", "🦾") 27 | rocket.display_message("Firing landing burn...", "🔥") 28 | rocket.display_message("Touchdown! Booster successfully recovered.", "🪂") 29 | -------------------------------------------------------------------------------- /APIs/python/Rocket_Lauch_Simulator/examples/spacex: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # Licensed under the Apache License, Version 2.0 (the "License"); 3 | # you may not use this file except in compliance with the License. 4 | # You may obtain a copy of the License at 5 | # 6 | # http://www.apache.org/licenses/LICENSE-2.0 7 | # 8 | # Unless required by applicable law or agreed to in writing, software 9 | # distributed under the License is distributed on an "AS IS" BASIS, 10 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | # See the License for the specific language governing permissions and 12 | # limitations under the License. 13 | 14 | """ 15 | Module utilizing SpaceX-specific operations for the RocketLaunch simulation. 16 | """ 17 | 18 | from rocket_launcher import RocketLaunch 19 | from rocket_launcher import spacex 20 | 21 | def main(): 22 | """ 23 | Simulate a SpaceX rocket launch with booster recovery operations. 24 | """ 25 | rocket = RocketLaunch("SpaceX Falcon 9", "Satellite Payload", "spacex") 26 | 27 | print("\nStarting SpaceX Rocket Launch Simulation...") 28 | rocket.simulate_launch() 29 | 30 | print("\nExecuting SpaceX Booster Recovery...") 31 | spacex.spacex_booster_recovery(rocket) 32 | 33 | if __name__ == "__main__": 34 | main() 35 | -------------------------------------------------------------------------------- /APIs/python/Rocket_Lauch_Simulator/examples/nasa: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # Licensed under the Apache License, Version 2.0 (the "License"); 3 | # you may not use this file except in compliance with the License. 4 | # You may obtain a copy of the License at 5 | # 6 | # http://www.apache.org/licenses/LICENSE-2.0 7 | # 8 | # Unless required by applicable law or agreed to in writing, software 9 | # distributed under the License is distributed on an "AS IS" BASIS, 10 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | # See the License for the specific language governing permissions and 12 | # limitations under the License. 13 | 14 | """ 15 | Module utilizing NASA-specific operations for the RocketLaunch simulation. 16 | """ 17 | 18 | from rocket_launcher import RocketLaunch 19 | from rocket_launcher import nasa 20 | 21 | def main(): 22 | """ 23 | Simulate a NASA rocket launch with Curiosity rover mission operations. 24 | """ 25 | rocket = RocketLaunch("NASA Mars Mission", "Curiosity Rover", "nasa") 26 | 27 | print("\nStarting NASA Rocket Launch Simulation...") 28 | rocket.simulate_launch() 29 | 30 | print("\nExecuting Curiosity Rover Mission Operations...") 31 | nasa.curiosity_mission_operations(rocket) 32 | 33 | if __name__ == "__main__": 34 | main() 35 | -------------------------------------------------------------------------------- /APIs/python/ROS2_Rocket_Launch_Simulator/setup.py: -------------------------------------------------------------------------------- 1 | # setup.py 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | from setuptools import setup, find_packages 15 | 16 | setup( 17 | name='rocket_launcher', 18 | version='0.1.0', 19 | description='A rocket launch simulation package.', 20 | author='Douglas Schilling Landgraf, Leonardo Rossetti, Dan Walsh', 21 | author_email='dougsland@redhat.com, lrossett@redhat.com, dwalsh@redhat.com', 22 | license='Apache License 2.0', 23 | packages=find_packages(), 24 | install_requires=[ 25 | 'rclpy', 26 | 'std_msgs', 27 | ], 28 | classifiers=[ 29 | 'Programming Language :: Python :: 3', 30 | 'License :: OSI Approved :: Apache Software License', 31 | 'Operating System :: OS Independent', 32 | ], 33 | python_requires='>=3.6', 34 | ) 35 | 36 | -------------------------------------------------------------------------------- /APIs/python/Rocket_Lauch_Simulator/rocket_launcher/nasa.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # Licensed under the Apache License, Version 2.0 (the "License"); 3 | # you may not use this file except in compliance with the License. 4 | # You may obtain a copy of the License at 5 | # 6 | # http://www.apache.org/licenses/LICENSE-2.0 7 | # 8 | # Unless required by applicable law or agreed to in writing, software 9 | # distributed under the License is distributed on an "AS IS" BASIS, 10 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | # See the License for the specific language governing permissions and 12 | # limitations under the License. 13 | 14 | """ 15 | Module containing NASA-specific operations for the RocketLaunch simulation. 16 | """ 17 | 18 | def curiosity_mission_operations(rocket): 19 | """ 20 | Special operations for NASA's Curiosity rover mission. 21 | 22 | Parameters: 23 | - rocket (RocketLaunch): Instance of the RocketLaunch class. 24 | """ 25 | rocket.display_message("Curiosity rover entering Martian atmosphere...", "🪐") 26 | rocket.display_message("Deploying parachute for descent...", "🪂") 27 | rocket.display_message("Initiating sky-crane maneuver...", "🛸") 28 | rocket.display_message("Curiosity rover has landed safely on Mars!", "🪨") 29 | rocket.display_message("Starting surface operations and data collection.", "🛰️") 30 | -------------------------------------------------------------------------------- /hack/bootc/README.md: -------------------------------------------------------------------------------- 1 | The bootc project is an open-source initiative that enables booting and updating operating systems using standard OCI (Open Container Initiative) or Docker container images. By encapsulating a complete OS—including the kernel, system libraries, and applications—within a container image, bootc facilitates transactional, in-place system updates and simplifies the deployment process. 2 | 3 | ### Ensure the image base is fetched 4 | 5 | ```console 6 | sudo podman pull quay.io/centos-bootc/centos-bootc:stream9 7 | ``` 8 | 9 | ### Install virt-install and virt-viewer 10 | 11 | ```console 12 | dnf install virt-install virt-viewer 13 | ``` 14 | 15 | ### Create the output directory 16 | 17 | ```console 18 | cd distro/json 19 | mkdir -p output 20 | ``` 21 | 22 | ### Install and start libvirt 23 | 24 | ```console 25 | dnf install libvirtd -y 26 | systemctl enabled libvirtd 27 | systemctl start libvirtd 28 | ``` 29 | 30 | ### Run Podman to create the Virtual Machine 31 | 32 | ```console 33 | git clone https://github.com/containers/space-grade-linux.git 34 | cd space-grade-linux/tools 35 | 36 | ./space-generate-and-run-distro 37 | 38 | Listing qcow2 image from distro/json/output/qcow2/... 39 | =========================================== 40 | 41 | Id Name State 42 | ------------------------------ 43 | 1 space-grade-linux running 44 | 45 | sudo podman exec -it space-grade-linux 46 | -------------------------------------------------------------------------------- /APIs/python/Rocket_Lauch_Simulator/examples/boeing: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # Licensed under the Apache License, Version 2.0 (the "License"); 3 | # you may not use this file except in compliance with the License. 4 | # You may obtain a copy of the License at 5 | # 6 | # http://www.apache.org/licenses/LICENSE-2.0 7 | # 8 | # Unless required by applicable law or agreed to in writing, software 9 | # distributed under the License is distributed on an "AS IS" BASIS, 10 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | # See the License for the specific language governing permissions and 12 | # limitations under the License. 13 | 14 | """ 15 | Module utilizing Boeing-specific operations for the RocketLaunch simulation. 16 | """ 17 | 18 | from rocket_launcher import RocketLaunch 19 | from rocket_launcher import boeing 20 | 21 | def main(): 22 | """ 23 | Simulate a Boeing rocket launch with payload deployment and return operations. 24 | """ 25 | rocket = RocketLaunch("Boeing Starliner", "Satellite Payload", "boeing") 26 | 27 | print("\nStarting Boeing Rocket Launch Simulation...") 28 | rocket.simulate_launch() 29 | 30 | print("\nExecuting Boeing Precision Payload Deployment...") 31 | boeing.boeing_precision_payload_deployment(rocket) 32 | 33 | print("\nExecuting Boeing Return and Landing...") 34 | boeing.boeing_return_and_landing(rocket) 35 | 36 | if __name__ == "__main__": 37 | main() 38 | -------------------------------------------------------------------------------- /APIs/python/Rocket_Lauch_Simulator/examples/blue_origin: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # Licensed under the Apache License, Version 2.0 (the "License"); 3 | # you may not use this file except in compliance with the License. 4 | # You may obtain a copy of the License at 5 | # 6 | # http://www.apache.org/licenses/LICENSE-2.0 7 | # 8 | # Unless required by applicable law or agreed to in writing, software 9 | # distributed under the License is distributed on an "AS IS" BASIS, 10 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | # See the License for the specific language governing permissions and 12 | # limitations under the License. 13 | 14 | """ 15 | Module utilizing Blue Origin-specific operations for the RocketLaunch simulation. 16 | """ 17 | 18 | from rocket_launcher import RocketLaunch 19 | from rocket_launcher import blue_origin 20 | 21 | def main(): 22 | """ 23 | Simulate a Blue Origin rocket launch with payload deployment and return operations. 24 | """ 25 | rocket = RocketLaunch("Blue Origin New Shepard", "Research Payload", "blue_origin") 26 | 27 | print("\nStarting Blue Origin Rocket Launch Simulation...") 28 | rocket.simulate_launch() 29 | 30 | print("\nExecuting Blue Origin Precision Payload Deployment...") 31 | blue_origin.blue_origin_payload_deployment(rocket) 32 | 33 | print("\nExecuting Blue Origin Return and Landing...") 34 | blue_origin.blue_origin_return_and_landing(rocket) 35 | 36 | if __name__ == "__main__": 37 | main() 38 | -------------------------------------------------------------------------------- /hack/bootc/json/space-grade-linux-distro.json: -------------------------------------------------------------------------------- 1 | { 2 | "sources": { 3 | "org.osbuild.curl": { 4 | "urls": { 5 | "sha256:c96a16541c504e29b6ef05bf4cf7432c207b39ef34ee9e944def00c5c48a8c09": "https://mirror.stream.centos.org/9-stream/BaseOS/x86_64/os/repodata/repomd.xml" 6 | } 7 | } 8 | }, 9 | "pipeline": { 10 | "stages": [ 11 | { 12 | "name": "org.osbuild.rpm", 13 | "options": { 14 | "packages": ["kernel", "bash", "coreutils", "grub2", "vim", "dracut", "epel-release"] 15 | } 16 | }, 17 | { 18 | "name": "org.osbuild.fstab", 19 | "options": { 20 | "filesystems": [ 21 | { 22 | "path": "/", 23 | "uuid": "123e4567-e89b-12d3-a456-426614174001", 24 | "type": "ext4" 25 | } 26 | ] 27 | } 28 | }, 29 | { 30 | "name": "org.osbuild.grub2", 31 | "options": { 32 | "rootfs": { 33 | "uuid": "123e4567-e89b-12d3-a456-426614174001" 34 | } 35 | } 36 | }, 37 | { 38 | "name": "org.osbuild.qemu", 39 | "options": { 40 | "format": "qcow2", 41 | "filename": "space-grade-linux.qcow2", 42 | "size": 10737418240 43 | } 44 | } 45 | ] 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /APIs/python/Autonomous_Drones/Parrot/anafi/autonomous_parrot_anafi: -------------------------------------------------------------------------------- 1 | # Licensed under the Apache License, Version 2.0 (the "License"); 2 | # you may not use this file except in compliance with the License. 3 | # You may obtain a copy of the License at 4 | # 5 | # http://www.apache.org/licenses/LICENSE-2.0 6 | # 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, 9 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | # See the License for the specific language governing permissions and 11 | # limitations under the License. 12 | 13 | import olympe 14 | import time 15 | from olympe.messages.ardrone3.Piloting import TakeOff, Landing, PCMD 16 | 17 | class DroneController: 18 | def __init__(self, drone_ip="192.168.42.1"): 19 | self.drone_ip = drone_ip 20 | self.drone = olympe.Drone(self.drone_ip) 21 | 22 | def connect(self): 23 | self.drone.connect() 24 | print("Connected to the drone.") 25 | 26 | def disconnect(self): 27 | self.drone.disconnect() 28 | print("Disconnected.") 29 | 30 | def take_off(self): 31 | print("Taking off...") 32 | self.drone(TakeOff()).wait(6) 33 | 34 | def land(self): 35 | print("Landing...") 36 | self.drone(Landing()).wait() 37 | 38 | def move(self, flag=1, roll=0, pitch=0, yaw=0, gaz=0, duration=5): 39 | print(f"Moving with roll={roll}, pitch={pitch}, yaw={yaw}, gaz={gaz} for {duration} seconds...") 40 | self.drone(PCMD(flag, roll, pitch, yaw, gaz, 0)).wait(duration) 41 | time.sleep(duration) 42 | 43 | # Example usage 44 | if __name__ == "__main__": 45 | controller = DroneController() 46 | try: 47 | controller.connect() 48 | controller.take_off() 49 | 50 | # Move forward 51 | controller.move(pitch=50, duration=5) 52 | 53 | # Move backward 54 | controller.move(pitch=-50, duration=5) 55 | 56 | # Land 57 | controller.land() 58 | finally: 59 | controller.disconnect() 60 | -------------------------------------------------------------------------------- /APIs/python/Rocket_Lauch_Simulator/rocket_launcher/boeing.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # Licensed under the Apache License, Version 2.0 (the "License"); 3 | # you may not use this file except in compliance with the License. 4 | # You may obtain a copy of the License at 5 | # 6 | # http://www.apache.org/licenses/LICENSE-2.0 7 | # 8 | # Unless required by applicable law or agreed to in writing, software 9 | # distributed under the License is distributed on an "AS IS" BASIS, 10 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | # See the License for the specific language governing permissions and 12 | # limitations under the License. 13 | 14 | """ 15 | Module containing Boeing-specific operations for the RocketLaunch simulation. 16 | """ 17 | 18 | def boeing_precision_payload_deployment(rocket): 19 | """ 20 | Special operations for Boeing rocket launch with a focus on payload deployment. 21 | 22 | Parameters: 23 | - rocket (RocketLaunch): Instance of the RocketLaunch class. 24 | """ 25 | rocket.display_message("Boeing rocket performing smooth stage transition...", "🔄") 26 | rocket.display_message("Ensuring precise orbital alignment...", "🛰️") 27 | rocket.display_message("Deploying payload with Boeing precision...", "🎯") 28 | rocket.display_message("Payload successfully deployed to orbit!", "🌌") 29 | rocket.display_message("Performing post-deployment checks and operations...", "✅") 30 | 31 | 32 | def boeing_return_and_landing(rocket): 33 | """ 34 | Special operations for returning the rocket and landing safely. 35 | 36 | Parameters: 37 | - rocket (RocketLaunch): Instance of the RocketLaunch class. 38 | """ 39 | rocket.display_message("Preparing for return journey to Earth...", "🌍") 40 | rocket.display_message("Initiating controlled descent...", "🛬") 41 | rocket.display_message("Adjusting aerodynamics for smooth reentry...", "☁️") 42 | rocket.display_message("Deploying landing gear and final adjustments...", "🛠️") 43 | rocket.display_message("Touchdown! Boeing rocket has landed safely.", "🏁") 44 | rocket.display_message("Mission complete with Boeing reliability.", "🎉") 45 | -------------------------------------------------------------------------------- /APIs/python/Rocket_Lauch_Simulator/rocket_launcher/blue_origin.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # Licensed under the Apache License, Version 2.0 (the "License"); 3 | # you may not use this file except in compliance with the License. 4 | # You may obtain a copy of the License at 5 | # 6 | # http://www.apache.org/licenses/LICENSE-2.0 7 | # 8 | # Unless required by applicable law or agreed to in writing, software 9 | # distributed under the License is distributed on an "AS IS" BASIS, 10 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | # See the License for the specific language governing permissions and 12 | # limitations under the License. 13 | 14 | """ 15 | Module containing Blue Origin-specific operations for the RocketLaunch simulation. 16 | """ 17 | 18 | def blue_origin_payload_deployment(rocket): 19 | """ 20 | Special operations for Blue Origin rocket payload deployment. 21 | 22 | Parameters: 23 | - rocket (RocketLaunch): Instance of the RocketLaunch class. 24 | """ 25 | rocket.display_message("Blue Origin rocket achieving stable suborbital trajectory...", "🚀") 26 | rocket.display_message("Preparing payload for deployment...", "📦") 27 | rocket.display_message("Deploying payload with precision...", "🎯") 28 | rocket.display_message("Payload successfully deployed in suborbital space!", "🌌") 29 | rocket.display_message("Post-deployment system checks in progress...", "🔍") 30 | 31 | 32 | def blue_origin_return_and_landing(rocket): 33 | """ 34 | Special operations for Blue Origin rocket's return and safe landing. 35 | 36 | Parameters: 37 | - rocket (RocketLaunch): Instance of the RocketLaunch class. 38 | """ 39 | rocket.display_message("Blue Origin rocket beginning return sequence...", "🔄") 40 | rocket.display_message("Initiating controlled descent with precision thrusters...", "🛬") 41 | rocket.display_message("Deploying landing gear and stabilizers...", "🛠️") 42 | rocket.display_message("Performing soft landing at designated site...", "🏞️") 43 | rocket.display_message("Rocket has landed safely. Ready for reuse.", "♻️") 44 | rocket.display_message("Blue Origin mission completed successfully!", "🎉") 45 | -------------------------------------------------------------------------------- /APIs/python/Rocket_Lauch_Simulator/rocket_launcher/lockheed_martin.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # Licensed under the Apache License, Version 2.0 (the "License"); 3 | # you may not use this file except in compliance with the License. 4 | # You may obtain a copy of the License at 5 | # 6 | # http://www.apache.org/licenses/LICENSE-2.0 7 | # 8 | # Unless required by applicable law or agreed to in writing, software 9 | # distributed under the License is distributed on an "AS IS" BASIS, 10 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | # See the License for the specific language governing permissions and 12 | # limitations under the License. 13 | 14 | """ 15 | Module containing Lockheed Martin-specific operations for the RocketLaunch simulation. 16 | """ 17 | 18 | def lockheed_martin_payload_deployment(rocket): 19 | """ 20 | Special operations for Lockheed Martin rocket payload deployment. 21 | 22 | Parameters: 23 | - rocket (RocketLaunch): Instance of the RocketLaunch class. 24 | """ 25 | rocket.display_message("Lockheed Martin rocket achieving stable geostationary orbit...", "🛰️") 26 | rocket.display_message("Verifying orbital precision with advanced navigation systems...", "📡") 27 | rocket.display_message("Deploying high-value payload with Lockheed precision...", "🎯") 28 | rocket.display_message("Payload successfully deployed to geostationary orbit!", "🌌") 29 | rocket.display_message("Performing thorough post-deployment diagnostics...", "✅") 30 | 31 | 32 | def lockheed_martin_return_and_landing(rocket): 33 | """ 34 | Special operations for Lockheed Martin rocket's return and landing. 35 | 36 | Parameters: 37 | - rocket (RocketLaunch): Instance of the RocketLaunch class. 38 | """ 39 | rocket.display_message("Initiating controlled descent to Earth...", "🛬") 40 | rocket.display_message("Adjusting thrusters for precision-guided reentry...", "🚀") 41 | rocket.display_message("Deploying thermal protection systems...", "🔥") 42 | rocket.display_message("Touchdown! Lockheed Martin rocket has landed safely.", "🏁") 43 | rocket.display_message("Mission completed with Lockheed Martin engineering excellence.", "🎉") 44 | -------------------------------------------------------------------------------- /src/engines/Containerfile-template-image-for-rocket-components-or-services: -------------------------------------------------------------------------------- 1 | # How to build 2 | # ================== 3 | # podman login quay.io 4 | # podman build --cap-add=sys_admin -t quay.io/qm-images/space-grade-linux-template-image-for-rocket-components-or-services:latest -f Containerfile-template-image-for-rocket-components-or-services 5 | # 6 | # Running example: 7 | # ================== 8 | # podman run -it --privileged --name spaceship-engine1 quay.io/qm-images/space-grade-linux-template-image-for-rocket-components-or-services:latest 9 | # podman run -it --privileged --name spaceship-payload quay.io/qm-images/space-grade-linux-template-image-for-rocket-components-or-services:latest 10 | # 11 | # Podman push into the repo 12 | # =========================== 13 | # podman push quay.io/qm-images/space-grade-linux-template-image-for-rocket-components-or-services:latest 14 | # 15 | #FROM registry.fedoraproject.org/fedora:latest 16 | FROM quay.io/centos/centos:stream9 17 | 18 | WORKDIR /root 19 | 20 | RUN echo "root:password" | chpasswd 21 | RUN dnf update -y && \ 22 | dnf install -y 'dnf-command(config-manager)' 23 | 24 | RUN dnf install -y epel-release # comment for Fedora build 25 | RUN dnf config-manager --set-enabled crb # comment for Fedora build 26 | 27 | RUN dnf -y install systemd procps-ng && dnf clean all 28 | 29 | RUN dnf install -y hostname \ 30 | git \ 31 | make \ 32 | gcc \ 33 | podman \ 34 | g++ \ 35 | bluechi-agent \ 36 | bluechi-ctl \ 37 | bluechi-selinux \ 38 | rpm-build \ 39 | container-selinux \ 40 | golang-github-cpuguy83-md2man \ 41 | selinux-policy \ 42 | iproute \ 43 | iproute-devel \ 44 | iputils \ 45 | systemd-devel \ 46 | selinux-policy-devel 47 | 48 | # Bluechi 49 | RUN systemctl enable bluechi-agent 50 | 51 | # Agent settings 52 | RUN echo -e "[bluechi-agent]\nNodeName=engineX-spaceship\nControllerHost=spaceship_base\nControllerPort=842\n" > /etc/bluechi/agent.conf.d/agent.conf 53 | 54 | # Dynamically fetch IP and append to /etc/hosts 55 | RUN IP=$(hostname -I | awk '{print $1}') & echo "$IP bluechi_controller" >> /etc/hosts 56 | 57 | #VOLUME ["/sys/fs/cgroup"] 58 | #CMD ["tail", "-f", "/dev/null"] 59 | ENTRYPOINT ["/sbin/init"] 60 | -------------------------------------------------------------------------------- /src/crew_espace_system/Containerfile-template-image-for-rocket-components-or-services: -------------------------------------------------------------------------------- 1 | # How to build 2 | # ================== 3 | # podman login quay.io 4 | # podman build --cap-add=sys_admin -t quay.io/qm-images/space-grade-linux-template-image-for-rocket-components-or-services:latest -f Containerfile-template-image-for-rocket-components-or-services 5 | # 6 | # Running example: 7 | # ================== 8 | # podman run -it --privileged --name spaceship-engine1 quay.io/qm-images/space-grade-linux-template-image-for-rocket-components-or-services:latest 9 | # podman run -it --privileged --name spaceship-payload quay.io/qm-images/space-grade-linux-template-image-for-rocket-components-or-services:latest 10 | # 11 | # Podman push into the repo 12 | # =========================== 13 | # podman push quay.io/qm-images/space-grade-linux-template-image-for-rocket-components-or-services:latest 14 | # 15 | #FROM registry.fedoraproject.org/fedora:latest 16 | FROM quay.io/centos/centos:stream9 17 | 18 | WORKDIR /root 19 | 20 | RUN echo "root:password" | chpasswd 21 | RUN dnf update -y && \ 22 | dnf install -y 'dnf-command(config-manager)' 23 | 24 | RUN dnf install -y epel-release # comment for Fedora build 25 | RUN dnf config-manager --set-enabled crb # comment for Fedora build 26 | 27 | RUN dnf -y install systemd procps-ng && dnf clean all 28 | 29 | RUN dnf install -y hostname \ 30 | git \ 31 | make \ 32 | gcc \ 33 | podman \ 34 | g++ \ 35 | bluechi-agent \ 36 | bluechi-ctl \ 37 | bluechi-selinux \ 38 | rpm-build \ 39 | container-selinux \ 40 | golang-github-cpuguy83-md2man \ 41 | selinux-policy \ 42 | iproute \ 43 | iproute-devel \ 44 | iputils \ 45 | systemd-devel \ 46 | selinux-policy-devel 47 | 48 | # Bluechi 49 | RUN systemctl enable bluechi-agent 50 | 51 | # Agent settings 52 | RUN echo -e "[bluechi-agent]\nNodeName=engineX-spaceship\nControllerHost=spaceship_base\nControllerPort=842\n" > /etc/bluechi/agent.conf.d/agent.conf 53 | 54 | # Dynamically fetch IP and append to /etc/hosts 55 | RUN IP=$(hostname -I | awk '{print $1}') & echo "$IP bluechi_controller" >> /etc/hosts 56 | 57 | #VOLUME ["/sys/fs/cgroup"] 58 | #CMD ["tail", "-f", "/dev/null"] 59 | ENTRYPOINT ["/sbin/init"] 60 | -------------------------------------------------------------------------------- /src/life_support_system/Containerfile-template-image-for-rocket-components-or-services: -------------------------------------------------------------------------------- 1 | # How to build 2 | # ================== 3 | # podman login quay.io 4 | # podman build --cap-add=sys_admin -t quay.io/qm-images/space-grade-linux-template-image-for-rocket-components-or-services:latest -f Containerfile-template-image-for-rocket-components-or-services 5 | # 6 | # Running example: 7 | # ================== 8 | # podman run -it --privileged --name spaceship-engine1 quay.io/qm-images/space-grade-linux-template-image-for-rocket-components-or-services:latest 9 | # podman run -it --privileged --name spaceship-payload quay.io/qm-images/space-grade-linux-template-image-for-rocket-components-or-services:latest 10 | # 11 | # Podman push into the repo 12 | # =========================== 13 | # podman push quay.io/qm-images/space-grade-linux-template-image-for-rocket-components-or-services:latest 14 | # 15 | #FROM registry.fedoraproject.org/fedora:latest 16 | FROM quay.io/centos/centos:stream9 17 | 18 | WORKDIR /root 19 | 20 | RUN echo "root:password" | chpasswd 21 | RUN dnf update -y && \ 22 | dnf install -y 'dnf-command(config-manager)' 23 | 24 | RUN dnf install -y epel-release # comment for Fedora build 25 | RUN dnf config-manager --set-enabled crb # comment for Fedora build 26 | 27 | RUN dnf -y install systemd procps-ng && dnf clean all 28 | 29 | RUN dnf install -y hostname \ 30 | git \ 31 | make \ 32 | gcc \ 33 | podman \ 34 | g++ \ 35 | bluechi-agent \ 36 | bluechi-ctl \ 37 | bluechi-selinux \ 38 | rpm-build \ 39 | container-selinux \ 40 | golang-github-cpuguy83-md2man \ 41 | selinux-policy \ 42 | iproute \ 43 | iproute-devel \ 44 | iputils \ 45 | systemd-devel \ 46 | selinux-policy-devel 47 | 48 | # Bluechi 49 | RUN systemctl enable bluechi-agent 50 | 51 | # Agent settings 52 | RUN echo -e "[bluechi-agent]\nNodeName=engineX-spaceship\nControllerHost=spaceship_base\nControllerPort=842\n" > /etc/bluechi/agent.conf.d/agent.conf 53 | 54 | # Dynamically fetch IP and append to /etc/hosts 55 | RUN IP=$(hostname -I | awk '{print $1}') & echo "$IP bluechi_controller" >> /etc/hosts 56 | 57 | #VOLUME ["/sys/fs/cgroup"] 58 | #CMD ["tail", "-f", "/dev/null"] 59 | ENTRYPOINT ["/sbin/init"] 60 | -------------------------------------------------------------------------------- /src/heat_shield_protection/Containerfile-template-image-for-rocket-components-or-services: -------------------------------------------------------------------------------- 1 | # How to build 2 | # ================== 3 | # podman login quay.io 4 | # podman build --cap-add=sys_admin -t quay.io/qm-images/space-grade-linux-template-image-for-rocket-components-or-services:latest -f Containerfile-template-image-for-rocket-components-or-services 5 | # 6 | # Running example: 7 | # ================== 8 | # podman run -it --privileged --name spaceship-engine1 quay.io/qm-images/space-grade-linux-template-image-for-rocket-components-or-services:latest 9 | # podman run -it --privileged --name spaceship-payload quay.io/qm-images/space-grade-linux-template-image-for-rocket-components-or-services:latest 10 | # 11 | # Podman push into the repo 12 | # =========================== 13 | # podman push quay.io/qm-images/space-grade-linux-template-image-for-rocket-components-or-services:latest 14 | # 15 | #FROM registry.fedoraproject.org/fedora:latest 16 | FROM quay.io/centos/centos:stream9 17 | 18 | WORKDIR /root 19 | 20 | RUN echo "root:password" | chpasswd 21 | RUN dnf update -y && \ 22 | dnf install -y 'dnf-command(config-manager)' 23 | 24 | RUN dnf install -y epel-release # comment for Fedora build 25 | RUN dnf config-manager --set-enabled crb # comment for Fedora build 26 | 27 | RUN dnf -y install systemd procps-ng && dnf clean all 28 | 29 | RUN dnf install -y hostname \ 30 | git \ 31 | make \ 32 | gcc \ 33 | podman \ 34 | g++ \ 35 | bluechi-agent \ 36 | bluechi-ctl \ 37 | bluechi-selinux \ 38 | rpm-build \ 39 | container-selinux \ 40 | golang-github-cpuguy83-md2man \ 41 | selinux-policy \ 42 | iproute \ 43 | iproute-devel \ 44 | iputils \ 45 | systemd-devel \ 46 | selinux-policy-devel 47 | 48 | # Bluechi 49 | RUN systemctl enable bluechi-agent 50 | 51 | # Agent settings 52 | RUN echo -e "[bluechi-agent]\nNodeName=engineX-spaceship\nControllerHost=spaceship_base\nControllerPort=842\n" > /etc/bluechi/agent.conf.d/agent.conf 53 | 54 | # Dynamically fetch IP and append to /etc/hosts 55 | RUN IP=$(hostname -I | awk '{print $1}') & echo "$IP bluechi_controller" >> /etc/hosts 56 | 57 | #VOLUME ["/sys/fs/cgroup"] 58 | #CMD ["tail", "-f", "/dev/null"] 59 | ENTRYPOINT ["/sbin/init"] 60 | -------------------------------------------------------------------------------- /src/flight_termination_system/Containerfile-template-image-for-rocket-components-or-services: -------------------------------------------------------------------------------- 1 | # How to build 2 | # ================== 3 | # podman login quay.io 4 | # podman build --cap-add=sys_admin -t quay.io/qm-images/space-grade-linux-template-image-for-rocket-components-or-services:latest -f Containerfile-template-image-for-rocket-components-or-services 5 | # 6 | # Running example: 7 | # ================== 8 | # podman run -it --privileged --name spaceship-engine1 quay.io/qm-images/space-grade-linux-template-image-for-rocket-components-or-services:latest 9 | # podman run -it --privileged --name spaceship-payload quay.io/qm-images/space-grade-linux-template-image-for-rocket-components-or-services:latest 10 | # 11 | # Podman push into the repo 12 | # =========================== 13 | # podman push quay.io/qm-images/space-grade-linux-template-image-for-rocket-components-or-services:latest 14 | # 15 | #FROM registry.fedoraproject.org/fedora:latest 16 | FROM quay.io/centos/centos:stream9 17 | 18 | WORKDIR /root 19 | 20 | RUN echo "root:password" | chpasswd 21 | RUN dnf update -y && \ 22 | dnf install -y 'dnf-command(config-manager)' 23 | 24 | RUN dnf install -y epel-release # comment for Fedora build 25 | RUN dnf config-manager --set-enabled crb # comment for Fedora build 26 | 27 | RUN dnf -y install systemd procps-ng && dnf clean all 28 | 29 | RUN dnf install -y hostname \ 30 | git \ 31 | make \ 32 | gcc \ 33 | podman \ 34 | g++ \ 35 | bluechi-agent \ 36 | bluechi-ctl \ 37 | bluechi-selinux \ 38 | rpm-build \ 39 | container-selinux \ 40 | golang-github-cpuguy83-md2man \ 41 | selinux-policy \ 42 | iproute \ 43 | iproute-devel \ 44 | iputils \ 45 | systemd-devel \ 46 | selinux-policy-devel 47 | 48 | # Bluechi 49 | RUN systemctl enable bluechi-agent 50 | 51 | # Agent settings 52 | RUN echo -e "[bluechi-agent]\nNodeName=engineX-spaceship\nControllerHost=spaceship_base\nControllerPort=842\n" > /etc/bluechi/agent.conf.d/agent.conf 53 | 54 | # Dynamically fetch IP and append to /etc/hosts 55 | RUN IP=$(hostname -I | awk '{print $1}') & echo "$IP bluechi_controller" >> /etc/hosts 56 | 57 | #VOLUME ["/sys/fs/cgroup"] 58 | #CMD ["tail", "-f", "/dev/null"] 59 | ENTRYPOINT ["/sbin/init"] 60 | -------------------------------------------------------------------------------- /src/Containerfile: -------------------------------------------------------------------------------- 1 | # How to build 2 | # ================== 3 | # podman login quay.io 4 | # podman build --cap-add=sys_admin -t quay.io/qm-images/space-grade-linux:latest -f Containerfile 5 | # podman run -it --net=host --name space-grade-container --privileged quay.io/qm-images/space-grade-linux:latest 6 | # podman push quay.io/qm-images/space-grade-linux:latest 7 | FROM quay.io/centos/centos:stream9 8 | 9 | WORKDIR /root 10 | 11 | RUN echo "root:password" | chpasswd 12 | RUN dnf update -y && \ 13 | dnf install -y 'dnf-command(config-manager)' 14 | 15 | RUN dnf install -y epel-release 16 | RUN dnf config-manager --set-enabled crb 17 | 18 | RUN dnf install -y hostname \ 19 | git \ 20 | make \ 21 | gcc \ 22 | podman \ 23 | g++ \ 24 | bluechi \ 25 | bluechi-agent \ 26 | bluechi-ctl \ 27 | bluechi-selinux \ 28 | rpm-build \ 29 | container-selinux \ 30 | golang-github-cpuguy83-md2man \ 31 | selinux-policy \ 32 | iproute \ 33 | iproute-devel \ 34 | iputils \ 35 | systemd-devel \ 36 | selinux-policy-devel 37 | #stellarium \ 38 | #stellarium-data 39 | 40 | RUN git clone https://github.com/containers/qm.git 41 | RUN cd qm && make rpm && cd rpmbuild/RPMS/noarch && dnf install -y ./*.rpm 42 | 43 | # or install via dnf install from the rhcontainerbot/qm REPO 44 | # RUN dnf copr enable -y rhcontainerbot/qm centos-stream-9-$(arch) 45 | # RUN dnf install qm -y 46 | 47 | # Disable blockage of sched_* for realtime 48 | RUN sed -i '/^SeccompProfile=\/usr\/share\/qm\/seccomp\.json/s/^/#/' /usr/share/containers/systemd/qm.container 49 | RUN /usr/share/qm/setup --skip-systemctl --hostname localrootfs 50 | 51 | 52 | # Bluechi 53 | 54 | RUN systemctl enable bluechi-controller && \ 55 | systemctl enable bluechi-agent 56 | 57 | # Controller settings 58 | RUN echo -e "[bluechi-controller]\nNodeName=bluechi_controller\nAllowedNodeNames=spaceship_base,engineX-spaceship\n" > /etc/bluechi/controller.conf.d/controller.conf 59 | 60 | # Agent settings 61 | RUN echo -e "[bluechi-agent]\nNodeName=engine1-spaceship\nControllerHost=127.0.0.1\nControllerPort=842\n" > /etc/bluechi/agent.conf.d/agent.conf 62 | 63 | # Dynamically fetch IP and append to /etc/hosts 64 | RUN IP=$(hostname -I | awk '{print $1}') && echo "$IP bluechi_controller" >> /etc/hosts 65 | 66 | ENTRYPOINT ["/sbin/init"] 67 | -------------------------------------------------------------------------------- /src/README.md: -------------------------------------------------------------------------------- 1 | ## Build 2 | 3 | If you are using [QM project](https://github.com/containers/qm.git) (as we suggest) for extra security layer for containers, install qm first or just skip the `podman qm bash` and execute podman commands. 4 | 5 | ``` 6 | sudo dnf install qm -y 7 | /usr/share/qm/setup 8 | ``` 9 | 10 | ```console 11 | # podman pull quay.io/qm-images/space-grade-linux:spaceship 12 | $ podman exec -it qm bash 13 | bash-5.2# podman pull quay.io/qm-images/space-grade-linux:rocket_engine 14 | ``` 15 | 16 | Create a specific network for the spaceship 17 | ```bash 18 | podman network create --subnet=192.168.100.0/24 spaceship-net 19 | $ podman exec -it qm bash 20 | podman network create --subnet=192.168.100.0/24 spaceship-net 21 | ``` 22 | 23 | ```console 24 | Start the spaceship base (single container) plus engines (containers) for your rocket: 25 | 26 | ```console 27 | #!/bin/bash 28 | 29 | podman run --replace -d --systemd=true --name spaceship --privileged \ 30 | --network spaceship-net --ip 192.168.100.100 \ 31 | quay.io/qm-images/space-grade-linux:spaceship 32 | 33 | for engine_number in {1..9}; do 34 | podman run --replace -d --systemd=true --name engine${engine_number}-spaceship \ 35 | --privileged --network spaceship-net --ip 192.168.100.1${engine_number} \ 36 | quay.io/qm-images/space-grade-linux:rocket_engine 37 | done 38 | ``` 39 | 40 | Looking to build manually the images? 41 | 42 | ```console 43 | podman build --cap-add=sys_admin -f Containerfile -t quay.io/qm-images/space-grade-linux:spaceship . 44 | podman build --cap-add=sys_admin -f engines/template-Containerfile_engine -t quay.io/qm-images/space-grade-linux:rocket_engine . 45 | ``` 46 | 47 | 48 | Workaround for permission deny affinity, until next release of crun 49 | 50 | on the host, add into /usr/share/qm/seccomp.json 51 | ``` 52 | { 53 | "names": [ 54 | "sched_setaffinity" 55 | ], 56 | "action": "SCMP_ACT_ALLOW", 57 | "args": [], 58 | "comment": "", 59 | "includes": {}, 60 | "excludes": {} 61 | }, 62 | ``` 63 | 64 | Restart QM 65 | ``` 66 | systemctl restart qm 67 | podman exec -it qm bash 68 | 69 | bash-5.2# podman run --replace -d --systemd=true --name spaceship --privileged quay.io/qm-images/space-grade-linux:spaceship 70 | 5d9285c1ef31f3ba3cc24b2caca92812110e24bb9bc2139f30fc50c4c1a6653c 71 | 72 | bash-5.2# 73 | ``` 74 | -------------------------------------------------------------------------------- /APIs/python/Moon/__ini__.py: -------------------------------------------------------------------------------- 1 | from datetime import date, timedelta 2 | import math 3 | 4 | class Moon: 5 | def __init__(self): 6 | # Reference date: New Moon on January 6, 2025 7 | self.reference_date = date(2025, 1, 6) 8 | self.lunar_cycle_length = 29.53 # Average length of a lunar cycle in days 9 | self.average_distance = 384400 # Average distance from Earth to Moon in km 10 | self.orbital_period = 27.32 # Orbital period in days 11 | 12 | def days_since_new_moon(self, target_date=None): 13 | """Calculate the number of days since the last new moon.""" 14 | if target_date is None: 15 | target_date = date.today() 16 | delta_days = (target_date - self.reference_date).days 17 | return delta_days % self.lunar_cycle_length 18 | 19 | def phase_of_moon(self, target_date=None): 20 | """Determine the current phase of the moon.""" 21 | days = self.days_since_new_moon(target_date) 22 | if days < 1.0: 23 | return "New Moon" 24 | elif days < 7.4: 25 | return "Waxing Crescent" 26 | elif days < 10.9: 27 | return "First Quarter" 28 | elif days < 14.8: 29 | return "Waxing Gibbous" 30 | elif days < 17.8: 31 | return "Full Moon" 32 | elif days < 22.1: 33 | return "Waning Gibbous" 34 | elif days < 25.7: 35 | return "Last Quarter" 36 | else: 37 | return "Waning Crescent" 38 | 39 | def next_full_moon(self): 40 | """Calculate the next full moon date.""" 41 | today = date.today() 42 | days = self.days_since_new_moon(today) 43 | days_to_full_moon = (14.8 - days) % self.lunar_cycle_length 44 | return today + timedelta(days=days_to_full_moon) 45 | 46 | def distance_from_earth(self): 47 | """Calculate the approximate distance from Earth to the Moon in km.""" 48 | days = self.days_since_new_moon() 49 | angle = (2 * math.pi * days) / self.orbital_period 50 | distance = self.average_distance * (1 + 0.0549 * math.cos(angle)) # Eccentricity adjustment 51 | return distance 52 | 53 | def visibility_percentage(self): 54 | """Calculate the percentage of the moon's surface illuminated.""" 55 | days = self.days_since_new_moon() 56 | illumination = 50 * (1 + math.cos(2 * math.pi * days / self.lunar_cycle_length)) 57 | return illumination 58 | 59 | def gravitational_force(self, mass): 60 | """Calculate the gravitational force between an object and the moon.""" 61 | G = 6.67430e-11 # Gravitational constant in m^3 kg^-1 s^-2 62 | moon_mass = 7.342e22 # Mass of the moon in kg 63 | distance_meters = self.distance_from_earth() * 1000 # Convert km to meters 64 | force = G * (moon_mass * mass) / (distance_meters ** 2) 65 | return force 66 | 67 | # Example usage 68 | #moon = Moon() 69 | #print(f"How many days have passed since most recent New Moon within the current lunar cycle. : {moon.days_since_new_moon():.2f}.") 70 | #print(f"Current moon phase: {moon.phase_of_moon()}") 71 | #print(f"Next full moon date: {moon.next_full_moon()}") 72 | #print(f"Distance from Earth: {moon.distance_from_earth():,.2f} km") 73 | #print(f"Visibility percentage: {moon.visibility_percentage():.2f}%") 74 | #mass_of_object = 80 # Mass in kg 75 | #print(f"Gravitational force on a {mass_of_object} kg object: {moon.gravitational_force(mass_of_object):.2e} N") 76 | -------------------------------------------------------------------------------- /APIs/python/Autonomous_Drones/README.md: -------------------------------------------------------------------------------- 1 | # Autonomous Drone Control with Joystick Integration (Initial Support for Tello) 2 | 3 | This project provides a Python-based framework for controlling drones, initially supporting DJI Tello drones using the `djitellopy` library. The script supports joystick integration for manual control and autonomous movements as a fallback. The framework is designed to be extensible for other drones by modifying the drone-specific logic. 4 | 5 | ## Features 6 | 7 | - **Wi-Fi Management:** Scans for available Wi-Fi networks and manages connections dynamically. 8 | - **Joystick Control:** Supports joystick-based manual control using `pygame`. 9 | - **Autonomous Control:** Performs predefined movements if no joystick is detected. 10 | - **Modular Design:** Can be extended to support additional drones. 11 | - **Safety Features:** Ensures safe landing and error handling during operations. 12 | - **Logging:** Provides detailed logging for debugging and operational insights. 13 | 14 | ## Requirements 15 | 16 | - Python 3.7 or later 17 | - A compatible drone (initially tested with DJI Tello) 18 | - PlayStation 5 controller (or any joystick supported by `pygame`) 19 | - USB-C cable for joystick connection 20 | - Dependencies: 21 | - `djitellopy` for Tello drone control: `pip install djitellopy` 22 | - `pygame` for joystick input: `pip install pygame` 23 | 24 | ## Installation 25 | 26 | 1. Clone the repository: 27 | ```bash 28 | git clone https://github.com/dougsland/autonomous_drones 29 | cd autonomous_drones 30 | ``` 31 | 32 | 2. Install the required dependencies: 33 | ```bash 34 | pip install -r requirements.txt 35 | ``` 36 | 37 | 3. Ensure the `nmcli` tool is installed and accessible for managing Wi-Fi connections. 38 | 39 | ## Usage 40 | 41 | 1. **Power on the Drone:** 42 | - For DJI Tello, power on the drone and wait for the Wi-Fi SSID to become available. 43 | 44 | 2. **Run the Script:** 45 | ```bash 46 | python main.py 47 | ``` 48 | 49 | 3. **Joystick Connection:** 50 | - Connect a joystick (e.g., PlayStation 5 controller) via USB-C for manual control. 51 | 52 | 4. **Autonomous Mode:** 53 | - If no joystick is detected, the script executes autonomous movements. 54 | 55 | ## Tested Configuration 56 | 57 | - [**Drone:** DJI Tello](https://www.amazon.com/DJI-Tello-Boost-Combo-Drone/dp/B0BTJ773C1) 58 |

59 | Autonomous Drone Image 1 60 |

61 | 62 | - [**Controller:** PlayStation 5 controller connected via USB-C](https://www.amazon.com/PlayStation-DualSense-Wireless-Controller/dp/B0CPXXWZGW/ref=sr_1_4?crid=V5QLJV24Y2UH&dib=eyJ2IjoiMSJ9.a_ghpjg03vvpon7A_D6F3Aeppp1-Cj82LIi8p57n29xZQkjts76dRPiyJjwcXro9ZDG_tZvJJo_FVW072LiJz7rVxY_YwwuVTDd4VO6oeDwXCAOwge1KuECYPraOBkOvw5Fam3UR6e7684z-C20bfXAyQ-x_t9K_NEIbMKFY1LyXjQHddreenPitO03pK59ZzC2-hS74KL9J1CrX_DLTxOhjKhxeYAsLhqgj-oOYSxA.EeHMzUYEEWj_1VEEAT_jmIvcReExAsDtIVHX6eawPiU&dib_tag=se&keywords=playstation+5+controller&qid=1735403675&sprefix=playstation+5+controlle%2Caps%2C150&sr=8-4) 63 |

64 | Autonomous Drone Image 1 65 |

66 | 67 | 68 | - **Operating System:** Linux-based system with `nmcli` for Wi-Fi management 69 | 70 | ## Extending to Other Drones 71 | 72 | To support other drones: 73 | 1. Replace the `Tello` class from `djitellopy` with the corresponding library or SDK for the target drone. 74 | 2. Update the methods related to drone-specific operations, such as `connect_drone`, `drone_logic`, and `process_joystick_input`. 75 | 76 | ## License 77 | 78 | This project is licensed under the Apache License, Version 2.0. See the [LICENSE](LICENSE) file for details. 79 | 80 | ## Contributing 81 | 82 | Contributions are welcome to extend support for additional drones and improve the framework. Please open an issue or submit a pull request. 83 | 84 | --- 85 | -------------------------------------------------------------------------------- /APIs/python/Rocket_Lauch_Simulator/rocket_launcher/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # Licensed under the Apache License, Version 2.0 (the "License"); 3 | # you may not use this file except in compliance with the License. 4 | # You may obtain a copy of the License at 5 | # 6 | # http://www.apache.org/licenses/LICENSE-2.0 7 | # 8 | # Unless required by applicable law or agreed to in writing, software 9 | # distributed under the License is distributed on an "AS IS" BASIS, 10 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | # See the License for the specific language governing permissions and 12 | # limitations under the License. 13 | 14 | import time 15 | 16 | class RocketLaunch: 17 | """ 18 | Class representing a rocket launch simulation with common functionality. 19 | 20 | Attributes: 21 | - rocket_name (str): Name of the rocket. 22 | - payload (str): Description of the payload. 23 | - mission_type (str): Type of mission (e.g., 'curiosity', 'spacex', or 'standard'). 24 | - current_stage (str): Current stage of the rocket launch. 25 | - stages (list): List of stages in the launch sequence. 26 | - stage_index (int): Index of the current stage in the stages list. 27 | - completed_stages (list): List of completed stages. 28 | 29 | Methods: 30 | - initialize_stages: Initialize launch stages based on the mission type. 31 | - delay: Introduce a delay for a given number of seconds. 32 | - display_message: Display a message with an accompanying emoji. 33 | - advance_stage: Advance to the next stage in the launch sequence. 34 | - reset_launch: Reset the launch sequence. 35 | - simulate_launch: Simulate the entire launch sequence. 36 | """ 37 | 38 | def __init__(self, rocket_name, payload, mission_type="standard"): 39 | """ 40 | Initialize a RocketLaunch instance. 41 | 42 | Parameters: 43 | - rocket_name (str): Name of the rocket. 44 | - payload (str): Description of the payload. 45 | - mission_type (str): Type of mission (e.g., 'curiosity', 'spacex', or 'standard'). 46 | """ 47 | self.rocket_name = rocket_name 48 | self.payload = payload 49 | self.mission_type = mission_type.lower() 50 | self.current_stage = "Initialization" 51 | self.stages = self.initialize_stages() 52 | self.stage_index = 0 53 | self.completed_stages = [] 54 | 55 | def initialize_stages(self): 56 | """ 57 | Initialize the stages based on the mission type. 58 | 59 | Returns: 60 | list: List of stages for the launch. 61 | """ 62 | base_stages = [ 63 | "Pre-Launch Preparations", 64 | "Ignition and Liftoff", 65 | "Ascent Stage", 66 | "Stage Separation", 67 | "Fairing Separation", 68 | "Orbital Insertion or Payload Deployment", 69 | "Stage Reentry and Recovery", 70 | "Post-Launch Operations" 71 | ] 72 | if self.mission_type == "curiosity": 73 | base_stages.append("Curiosity Mission Operations") 74 | elif self.mission_type == "spacex": 75 | base_stages.append("SpaceX Booster Recovery") 76 | return base_stages 77 | 78 | def delay(self, seconds=2): 79 | """ 80 | Introduce a delay for a given number of seconds. 81 | 82 | Parameters: 83 | - seconds (int): Number of seconds to delay. 84 | """ 85 | time.sleep(seconds) 86 | 87 | def display_message(self, message, emoji): 88 | """ 89 | Display a message with an accompanying emoji. 90 | 91 | Parameters: 92 | - message (str): Message to be displayed. 93 | - emoji (str): Emoji to accompany the message. 94 | """ 95 | print(f"{emoji} {message}") 96 | self.delay() 97 | 98 | def advance_stage(self): 99 | """ 100 | Advance to the next stage in the rocket launch sequence. 101 | Calls the method corresponding to the current stage. 102 | """ 103 | if self.stage_index < len(self.stages): 104 | self.current_stage = self.stages[self.stage_index] 105 | self.completed_stages.append(self.current_stage) 106 | print(f"\n--- Stage: {self.current_stage} ---") 107 | self.stage_index += 1 108 | else: 109 | print("🚀 Rocket launch sequence is complete! 🎉") 110 | 111 | def reset_launch(self): 112 | """ 113 | Reset the launch sequence, allowing it to be restarted. 114 | """ 115 | self.current_stage = "Initialization" 116 | self.stage_index = 0 117 | self.completed_stages = [] 118 | print(f"🔄 Launch sequence for {self.rocket_name} has been reset.") 119 | 120 | def simulate_launch(self): 121 | """ 122 | Simulate the entire launch sequence. 123 | Advances through all stages and calls the respective methods for each stage. 124 | """ 125 | print(f"🚀 Starting launch sequence for {self.rocket_name} with payload: {self.payload} 🚀") 126 | while self.stage_index < len(self.stages): 127 | self.advance_stage() 128 | print("🎉 Launch sequence completed successfully! 🎉") 129 | -------------------------------------------------------------------------------- /APIs/python/Cameras/IntelRealSense/435i/__init__.py: -------------------------------------------------------------------------------- 1 | import pyrealsense2 as rs 2 | import numpy as np 3 | import cv2 4 | 5 | class Intel435iManager: 6 | def __init__(self): 7 | """Initialize the Intel 435i camera pipeline and configuration.""" 8 | self.pipeline = rs.pipeline() 9 | self.config = rs.config() 10 | self.running = False 11 | 12 | def initialize(self, width=640, height=480, fps=30): 13 | """Configure the camera stream.""" 14 | self.config.enable_stream(rs.stream.depth, width, height, rs.format.z16, fps) 15 | self.config.enable_stream(rs.stream.color, width, height, rs.format.bgr8, fps) 16 | print("Camera initialized.") 17 | 18 | def start(self): 19 | """Start the camera pipeline.""" 20 | try: 21 | self.pipeline.start(self.config) 22 | self.running = True 23 | print("Camera started.") 24 | except Exception as e: 25 | print(f"Error starting the camera: {e}") 26 | 27 | def stop(self): 28 | """Stop the camera pipeline.""" 29 | if self.running: 30 | self.pipeline.stop() 31 | self.running = False 32 | print("Camera stopped.") 33 | 34 | def get_frames(self): 35 | """Capture a single frame of depth and color data.""" 36 | if not self.running: 37 | print("Camera is not running. Start the camera first.") 38 | return None, None, None 39 | 40 | try: 41 | frames = self.pipeline.wait_for_frames() 42 | depth_frame = frames.get_depth_frame() 43 | color_frame = frames.get_color_frame() 44 | 45 | if not depth_frame or not color_frame: 46 | print("Failed to capture frames.") 47 | return None, None, None 48 | 49 | depth_image = np.asanyarray(depth_frame.get_data()) 50 | color_image = np.asanyarray(color_frame.get_data()) 51 | return depth_frame, depth_image, color_image 52 | except Exception as e: 53 | print(f"Error capturing frames: {e}") 54 | return None, None, None 55 | 56 | def get_distance(self, depth_frame, x, y): 57 | """ 58 | Get the distance at a specific pixel (x, y). 59 | 60 | Parameters: 61 | depth_frame (rs.frame): The depth frame from which to extract distance. 62 | x (int): The x-coordinate of the pixel. 63 | y (int): The y-coordinate of the pixel. 64 | 65 | Returns: 66 | float: The distance in meters at the given pixel. 67 | """ 68 | if not depth_frame: 69 | print("Invalid depth frame.") 70 | return None 71 | distance = depth_frame.get_distance(x, y) 72 | return distance 73 | 74 | def save_snapshot(self, color_image, depth_image=None, save_depth=False, color_path="color_snapshot.png", depth_path="depth_snapshot.png"): 75 | """ 76 | Save color and optionally depth images as snapshots. 77 | 78 | Parameters: 79 | color_image (np.ndarray): The color image to save. 80 | depth_image (np.ndarray): The depth image to save (optional). 81 | save_depth (bool): Whether to save the depth image. Default is False. 82 | color_path (str): Path to save the color image. 83 | depth_path (str): Path to save the depth image (if enabled). 84 | """ 85 | try: 86 | # Save the color image 87 | cv2.imwrite(color_path, color_image) 88 | print(f"Color snapshot saved as {color_path}.") 89 | 90 | # Save the depth image only if requested 91 | if save_depth and depth_image is not None: 92 | normalized_depth = cv2.normalize(depth_image, None, 0, 255, cv2.NORM_MINMAX) 93 | normalized_depth = cv2.convertScaleAbs(normalized_depth) 94 | cv2.imwrite(depth_path, normalized_depth) 95 | print(f"Depth snapshot saved as {depth_path}.") 96 | except Exception as e: 97 | print(f"Error saving snapshots: {e}") 98 | 99 | def convert_to_readable_units(self, distance_in_meters): 100 | """ 101 | Convert distance from meters to human-readable units. 102 | 103 | Parameters: 104 | distance_in_meters (float): The distance in meters. 105 | 106 | Returns: 107 | dict: A dictionary with distances in meters, centimeters, and inches. 108 | """ 109 | return { 110 | "meters": round(distance_in_meters, 3), 111 | "centimeters": round(distance_in_meters * 100, 1), 112 | "inches": round(distance_in_meters * 39.3701, 2) 113 | } 114 | 115 | def __del__(self): 116 | """Ensure the camera pipeline is stopped when the object is deleted.""" 117 | if self.running: 118 | self.stop() 119 | 120 | # Example of usage 121 | #if __name__ == "__main__": 122 | # camera = Intel435iManager() 123 | # 124 | # # Initialize camera 125 | # camera.initialize() 126 | # 127 | # # Start camera 128 | # camera.start() 129 | # 130 | # Capture frames 131 | # depth_frame, depth_image, color_image = camera.get_frames() 132 | # 133 | # if depth_frame: 134 | # # Get distance at specific points (e.g., center of the frame) 135 | # height, width = depth_image.shape 136 | # center_x, center_y = width // 2, height // 2 137 | # 138 | # center_distance = camera.get_distance(depth_frame, center_x, center_y) 139 | # if center_distance > 0: # Check if the distance is valid 140 | # center_readable = camera.convert_to_readable_units(center_distance) 141 | # print(f"Distance at center ({center_x}, {center_y}): {center_readable}") 142 | # else: 143 | # print(f"Distance at center ({center_x}, {center_y}) is out of range.") 144 | # 145 | # Save color snapshot; depth snapshot is optional 146 | # camera.save_snapshot(color_image, depth_image, save_depth=False) 147 | # 148 | # Stop the camera 149 | # camera.stop() 150 | -------------------------------------------------------------------------------- /APIs/python/ROS2_Rocket_Launch_Simulator/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # Licensed under the Apache License, Version 2.0 (the "License"); 3 | # you may not use this file except in compliance with the License. 4 | # You may obtain a copy of the License at 5 | # 6 | # http://www.apache.org/licenses/LICENSE-2.0 7 | # 8 | # Unless required by applicable law or agreed to in writing, software 9 | # distributed under the License is distributed on an "AS IS" BASIS, 10 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | # See the License for the specific language governing permissions and 12 | # limitations under the License. 13 | 14 | """ 15 | Common module for RocketLaunch simulation. 16 | Provides the base RocketLaunch class and common operations. 17 | """ 18 | 19 | import time 20 | import rclpy 21 | from rclpy.node import Node as BaseNode 22 | from std_msgs.msg import String 23 | 24 | 25 | class RocketLaunch(BaseNode): 26 | """ 27 | Class representing a rocket launch simulation with common functionality. 28 | 29 | Attributes: 30 | - rocket_name (str): Name of the rocket. 31 | - payload (str): Description of the payload. 32 | - mission_type (str): Type of mission (e.g., 'curiosity', 'spacex', or 'standard'). 33 | - current_stage (str): Current stage of the rocket launch. 34 | - stages (list): List of stages in the launch sequence. 35 | - stage_index (int): Index of the current stage in the stages list. 36 | - completed_stages (list): List of completed stages. 37 | 38 | Methods: 39 | - initialize_stages: Initialize launch stages based on the mission type. 40 | - delay: Introduce a delay for a given number of seconds. 41 | - display_message: Display a message with an accompanying emoji. 42 | - handler: Handle messages received on the 'rocket_launch' ROS2 topic. 43 | - advance_stage: Advance to the next stage in the launch sequence. 44 | - reset_launch: Reset the launch sequence. 45 | - simulate_launch: Simulate the entire launch sequence. 46 | """ 47 | 48 | def __init__(self, rocket_name, payload, mission_type="standard"): 49 | """ 50 | Initialize a RocketLaunch instance and a ROS2 Node. 51 | 52 | Parameters: 53 | - rocket_name (str): Name of the rocket. 54 | - payload (str): Description of the payload. 55 | - mission_type (str): Type of mission (e.g., 'curiosity', 'spacex', or 'standard'). 56 | """ 57 | super().__init__('rocket_launch_node') 58 | self.rocket_name = rocket_name 59 | self.payload = payload 60 | self.mission_type = mission_type.lower() 61 | self.current_stage = "Initialization" 62 | self.stages = self.initialize_stages() 63 | self.stage_index = 0 64 | self.completed_stages = [] 65 | self.sub = self.create_subscription( 66 | String, 67 | 'rocket_launch', 68 | self.handler, 69 | 10 70 | ) 71 | 72 | def initialize_stages(self): 73 | """ 74 | Initialize the stages based on the mission type. 75 | 76 | Returns: 77 | list: List of stages for the launch. 78 | """ 79 | base_stages = [ 80 | "Pre-Launch Preparations", 81 | "Ignition and Liftoff", 82 | "Ascent Stage", 83 | "Stage Separation", 84 | "Fairing Separation", 85 | "Orbital Insertion or Payload Deployment", 86 | "Stage Reentry and Recovery", 87 | "Post-Launch Operations" 88 | ] 89 | if self.mission_type == "curiosity": 90 | base_stages.append("Curiosity Mission Operations") 91 | elif self.mission_type == "spacex": 92 | base_stages.append("SpaceX Booster Recovery") 93 | return base_stages 94 | 95 | def delay(self, seconds=2): 96 | """ 97 | Introduce a delay for a given number of seconds. 98 | 99 | Parameters: 100 | - seconds (int): Number of seconds to delay. 101 | """ 102 | time.sleep(seconds) 103 | 104 | def display_message(self, message, emoji): 105 | """ 106 | Display a message with an accompanying emoji. 107 | 108 | Parameters: 109 | - message (str): Message to be displayed. 110 | - emoji (str): Emoji to accompany the message. 111 | """ 112 | print(f"{emoji} {message}") 113 | self.delay() 114 | 115 | def handler(self, msg): 116 | """ 117 | Handle messages received on the 'rocket_launch' topic. 118 | 119 | Parameters: 120 | - msg (String): Received message. 121 | """ 122 | self.get_logger().info(f'Received rocket_launch data: {msg.data}') 123 | 124 | def advance_stage(self): 125 | """ 126 | Advance to the next stage in the rocket launch sequence. 127 | Calls the method corresponding to the current stage. 128 | """ 129 | if self.stage_index < len(self.stages): 130 | stage_method_name = ( 131 | self.stages[self.stage_index] 132 | .lower() 133 | .replace(" ", "_") 134 | .replace("-", "_") 135 | .replace("/", "_") 136 | ) 137 | stage_method = getattr(self, stage_method_name, None) 138 | if stage_method: 139 | self.current_stage = self.stages[self.stage_index] 140 | self.completed_stages.append(self.current_stage) 141 | print(f"\n--- Stage: {self.current_stage} ---") 142 | stage_method() 143 | self.stage_index += 1 144 | else: 145 | print(f"Error: No method found for stage '{self.stages[self.stage_index]}'") 146 | else: 147 | print("🚀 Rocket launch sequence is complete! 🎉") 148 | 149 | def reset_launch(self): 150 | """ 151 | Reset the launch sequence, allowing it to be restarted. 152 | """ 153 | self.current_stage = "Initialization" 154 | self.stage_index = 0 155 | self.completed_stages = [] 156 | print(f"🔄 Launch sequence for {self.rocket_name} has been reset.") 157 | 158 | def simulate_launch(self): 159 | """ 160 | Simulate the entire launch sequence. 161 | Advances through all stages and calls the respective methods for each stage. 162 | """ 163 | print(f"🚀 Starting launch sequence for {self.rocket_name} with payload: {self.payload} 🚀") 164 | while self.stage_index < len(self.stages): 165 | self.advance_stage() 166 | print("🎉 Launch sequence completed successfully! 🎉") 167 | -------------------------------------------------------------------------------- /APIs/python/Autonomous_Drones/dji/tello/autonomous_drones: -------------------------------------------------------------------------------- 1 | # Licensed under the Apache License, Version 2.0 (the "License"); 2 | # You may not use this file except in compliance with the License. 3 | # You may obtain a copy of the License at 4 | # 5 | # http://www.apache.org/licenses/LICENSE-2.0 6 | # 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, 9 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | # See the License for the specific language governing permissions and 11 | # limitations under the License. 12 | 13 | import subprocess 14 | import logging 15 | from time import sleep 16 | import pygame 17 | from djitellopy import Tello # Ensure this library is installed: pip install djitellopy 18 | 19 | # Configure logging 20 | logging.basicConfig(level=logging.INFO, format='[%(levelname)s] %(message)s') 21 | 22 | def run_command(command): 23 | """Run a shell command and capture the output.""" 24 | try: 25 | logging.debug(f"Executing command: {command}") 26 | result = subprocess.run(command, shell=True, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) 27 | logging.debug(f"Command succeeded: {result.stdout.strip()}") 28 | return result.stdout.strip() 29 | except subprocess.CalledProcessError as e: 30 | logging.error(f"Command failed: {command}\nError: {e.stderr.strip()}") 31 | return None 32 | 33 | def scan_wifi_networks(): 34 | """Scan for available Wi-Fi networks.""" 35 | logging.debug("Scanning for available Wi-Fi networks...") 36 | output = run_command("nmcli -t -f ssid dev wifi") 37 | if output: 38 | networks = set(filter(None, map(str.strip, output.splitlines()))) 39 | logging.debug(f"Available Wi-Fi networks: {networks}") 40 | return networks 41 | logging.error("Failed to scan for Wi-Fi networks.") 42 | return set() 43 | 44 | def check_active_wifi_connection(): 45 | """Check the currently active Wi-Fi connection.""" 46 | logging.info("Checking current Wi-Fi connection...") 47 | output = run_command("nmcli -t -f active,ssid dev wifi | grep '^yes'") 48 | if output: 49 | active_network = output.split(":")[1] 50 | logging.info(f"Currently connected to: {active_network}") 51 | return active_network 52 | logging.warning("No active Wi-Fi connection detected.") 53 | return None 54 | 55 | def disconnect_from_current_wifi(): 56 | """Disconnect from the currently active Wi-Fi network.""" 57 | active_network = check_active_wifi_connection() 58 | if not active_network: 59 | logging.warning("No active network to disconnect.") 60 | return True 61 | 62 | # Get list of active connections 63 | active_connections = run_command("nmcli -t -f NAME connection show --active") 64 | if not active_connections or active_network not in active_connections.splitlines(): 65 | logging.warning(f"Active connection '{active_network}' not found in NetworkManager. Skipping disconnection.") 66 | return True 67 | 68 | logging.info(f"Disconnecting from current network: {active_network}") 69 | if run_command(f"nmcli connection down '{active_network}'"): 70 | logging.info(f"Successfully disconnected from network: {active_network}") 71 | return True 72 | else: 73 | logging.error(f"Failed to disconnect from the network: {active_network}") 74 | return False 75 | 76 | def connect_to_tello_wifi(tello_ssid, retries=3): 77 | """Connect to the Tello Wi-Fi network with retries.""" 78 | for attempt in range(retries): 79 | logging.info(f"Attempt {attempt + 1}/{retries}: Connecting to Tello Wi-Fi: {tello_ssid}") 80 | if run_command(f"nmcli device wifi connect '{tello_ssid}'"): 81 | sleep(5) # Allow time for the connection to stabilize 82 | if check_active_wifi_connection() == tello_ssid: 83 | logging.info(f"Successfully connected to Tello Wi-Fi: {tello_ssid}") 84 | return True 85 | else: 86 | logging.warning("Verification failed after connection attempt.") 87 | else: 88 | logging.warning(f"Failed to connect to {tello_ssid} on attempt {attempt + 1}. Retrying...") 89 | sleep(2) 90 | logging.error(f"Failed to connect to Tello Wi-Fi after {retries} attempts.") 91 | return False 92 | 93 | def initialize_joystick(): 94 | """Initialize the joystick and return the joystick instance.""" 95 | pygame.init() 96 | pygame.joystick.init() 97 | 98 | joystick_count = pygame.joystick.get_count() 99 | logging.info(f"Number of joysticks detected: {joystick_count}") 100 | 101 | if joystick_count == 0: 102 | logging.warning("No joystick detected. Falling back to autonomous mode.") 103 | return None 104 | 105 | joystick = pygame.joystick.Joystick(0) 106 | joystick.init() 107 | logging.info(f"Joystick initialized: {joystick.get_name()}") 108 | return joystick 109 | 110 | def process_joystick_input(drone, joystick): 111 | """Process joystick input to control the drone.""" 112 | pygame.event.pump() # Update joystick events 113 | axis_forward_back = joystick.get_axis(1) # Forward/Backward 114 | axis_left_right = joystick.get_axis(0) # Left/Right 115 | axis_up_down = joystick.get_axis(2) # Up/Down 116 | axis_yaw = joystick.get_axis(3) # Rotation 117 | 118 | # Map axis values to drone speeds 119 | forward_speed = int(-axis_forward_back * 100) # Forward is negative 120 | turn_speed = int(axis_left_right * 100) 121 | up_down_speed = int(axis_up_down * 100) 122 | yaw_speed = int(axis_yaw * 100) 123 | 124 | # Debugging joystick inputs 125 | logging.debug(f"Joystick axes: Forward/Backward={forward_speed}, Left/Right={turn_speed}, Up/Down={up_down_speed}, Yaw={yaw_speed}") 126 | 127 | # Send RC control to the drone 128 | drone.send_rc_control(turn_speed, forward_speed, up_down_speed, yaw_speed) 129 | 130 | def connect_drone(drone, retries=3, delay=5): 131 | """Retry drone connection if it fails.""" 132 | for attempt in range(retries): 133 | try: 134 | logging.info(f"Connecting to Tello (Attempt {attempt + 1}/{retries})...") 135 | drone.connect() 136 | logging.info("Connection successful.") 137 | return True 138 | except Exception as e: 139 | logging.warning(f"Connection attempt {attempt + 1} failed: {e}") 140 | sleep(delay) 141 | logging.error("Failed to connect to Tello after multiple attempts.") 142 | return False 143 | 144 | def drone_logic(drone): 145 | """Control the drone to take off, check joystick input, and perform movements.""" 146 | logging.info("Drone is taking off...") 147 | 148 | # Pre-checks before takeoff 149 | battery = drone.get_battery() 150 | logging.info(f"Battery level: {battery}%") 151 | if battery < 20: 152 | logging.error("Battery too low for takeoff.") 153 | return 154 | 155 | joystick = initialize_joystick() 156 | 157 | try: 158 | drone.takeoff() 159 | if joystick: 160 | logging.info("Joystick detected. Starting manual control.") 161 | while True: 162 | process_joystick_input(drone, joystick) 163 | sleep(0.1) # Poll joystick input every 100ms 164 | else: 165 | logging.info("No joystick detected. Performing autonomous movements...") 166 | logging.info("Moving forward for 3 seconds...") 167 | drone.send_rc_control(0, 50, 0, 0) # Forward 168 | sleep(3) 169 | 170 | logging.info("Moving backward for 3 seconds...") 171 | drone.send_rc_control(0, -50, 0, 0) # Backward 172 | sleep(3) 173 | 174 | drone.send_rc_control(0, 0, 0, 0) # Stop movement 175 | except Exception as e: 176 | logging.error(f"An error occurred during flight: {e}") 177 | finally: 178 | logging.info("Landing the drone...") 179 | drone.land() 180 | pygame.quit() 181 | 182 | # Main Execution 183 | def main(): 184 | tello_ssid = "TELLO-314B32" 185 | logging.info("Initializing Tello connection process...") 186 | 187 | available_networks = scan_wifi_networks() 188 | if tello_ssid not in available_networks: 189 | logging.critical(f"Tello Wi-Fi '{tello_ssid}' not detected. Ensure the drone is powered on and within range.") 190 | return 191 | 192 | if not disconnect_from_current_wifi(): 193 | logging.error("Failed to disconnect from the current Wi-Fi network.") 194 | return 195 | 196 | if not connect_to_tello_wifi(tello_ssid): 197 | logging.error("Unable to establish a connection to Tello Wi-Fi.") 198 | return 199 | 200 | logging.info("Tello Wi-Fi connection established successfully.") 201 | drone = Tello() 202 | 203 | if connect_drone(drone): 204 | try: 205 | drone_logic(drone) 206 | except Exception as e: 207 | logging.error(f"An error occurred while controlling the drone: {e}") 208 | try: 209 | drone.land() # Ensure the drone lands safely in case of error 210 | except Exception as land_error: 211 | logging.error(f"An error occurred during landing: {land_error}") 212 | else: 213 | logging.critical("Unable to connect to the Tello drone.") 214 | 215 | if __name__ == "__main__": 216 | main() 217 | -------------------------------------------------------------------------------- /APIs/python/Robotic_Arms/waveshare/armcontroller.py: -------------------------------------------------------------------------------- 1 | # Licensed under the Apache License, Version 2.0 (the \"License\"); 2 | # you may not use this file except in compliance with the License. 3 | # You may obtain a copy of the License at 4 | # 5 | # http://www.apache.org/licenses/LICENSE-2.0 6 | # 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an \"AS IS\" BASIS, 9 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | # See the License for the specific language governing permissions and 11 | # limitations under the License. 12 | 13 | import requests 14 | import math 15 | 16 | class RoArmM2S: 17 | def __init__(self, ip_address): 18 | self.base_url = f"http://{ip_address}/js?json=" 19 | 20 | def send_command(self, command_json): 21 | url = self.base_url + command_json 22 | response = requests.get(url) 23 | return response.text 24 | 25 | # WiFi Settings 26 | def cmd_wifi_on_boot(self): 27 | return self.send_command('{"T":401,"cmd":3}') 28 | 29 | def cmd_set_ap(self, ssid, password): 30 | return self.send_command(f'{{"T":402,"ssid":"{ssid}","password":"{password}"}}') 31 | 32 | def cmd_set_sta(self, ssid, password): 33 | return self.send_command(f'{{"T":403,"ssid":"{ssid}","password":"{password}"}}') 34 | 35 | def cmd_wifi_apsta(self, ap_ssid, ap_password, sta_ssid, sta_password): 36 | return self.send_command(f'{{"T":404,"ap_ssid":"{ap_ssid}","ap_password":"{ap_password}","sta_ssid":"{sta_ssid}","sta_password":"{sta_password}"}}') 37 | 38 | def cmd_wifi_info(self): 39 | return self.send_command('{"T":405}') 40 | 41 | def cmd_wifi_config_create_by_status(self): 42 | return self.send_command('{"T":406}') 43 | 44 | def cmd_wifi_config_create_by_input(self, mode, ap_ssid, ap_password, sta_ssid, sta_password): 45 | return self.send_command(f'{{"T":407,"mode":{mode},"ap_ssid":"{ap_ssid}","ap_password":"{ap_password}","sta_ssid":"{sta_ssid}","sta_password":"{sta_password}"}}') 46 | 47 | # ESP-NOW Settings 48 | def cmd_broadcast_follower(self, mode, mac): 49 | return self.send_command(f'{{"T":300,"mode":{mode},"mac":"{mac}"}}') 50 | 51 | def cmd_esp_now_config(self, mode, dev, cmd, megs): 52 | return self.send_command(f'{{"T":301,"mode":{mode},"dev":{dev},"cmd":{cmd},"megs":{megs}}}') 53 | 54 | def cmd_get_mac_address(self): 55 | return self.send_command('{"T":302}') 56 | 57 | def cmd_esp_now_add_follower(self, mac): 58 | return self.send_command(f'{{"T":303,"mac":"{mac}"}}') 59 | 60 | def cmd_esp_now_remove_follower(self, mac): 61 | return self.send_command(f'{{"T":304,"mac":"{mac}"}}') 62 | 63 | def cmd_esp_now_many_ctrl(self, dev, b, s, e, h, cmd, megs): 64 | return self.send_command(f'{{"T":305,"dev":{dev},"b":{b},"s":{s},"e":{e},"h":{h},"cmd":{cmd},"megs":"{megs}"}}') 65 | 66 | def cmd_esp_now_single(self, mac, dev, b, s, e, h, cmd, megs): 67 | return self.send_command(f'{{"T":306,"mac":"{mac}","dev":{dev},"b":{b},"s":{s},"e":{e},"h":{h},"cmd":{cmd},"megs":"{megs}"}}') 68 | 69 | # Torque Control 70 | def cmd_torque_ctrl(self, cmd): 71 | return self.send_command(f'{{"T":210,"cmd":{cmd}}}') 72 | 73 | # Dynamic Adaptation 74 | def cmd_set_new_x(self, mode, b, s, e, h): 75 | return self.send_command(f'{{"T":112,"mode":{mode},"b":{b},"s":{s},"e":{e},"h":{h}}}') 76 | 77 | # Moving Control 78 | def cmd_move_init(self): 79 | return self.send_command('{"T":100}') 80 | 81 | def cmd_single_joint_ctrl(self, joint, rad, spd, acc): 82 | return self.send_command(f'{{"T":101,"joint":{joint},"rad":{rad},"spd":{spd},"acc":{acc}}}') 83 | 84 | def cmd_joints_rad_ctrl(self, base, shoulder, elbow, hand, spd, acc): 85 | return self.send_command(f'{{"T":102,"base":{base},"shoulder":{shoulder},"elbow":{elbow},"hand":{hand},"spd":{spd},"acc":{acc}}}') 86 | 87 | def cmd_xyzt_goal_ctrl(self, x, y, z, t, spd): 88 | return self.send_command(f'{{"T":104,"x":{x},"y":{y},"z":{z},"t":{t},"spd":{spd}}}') 89 | 90 | def cmd_xyzt_direct_ctrl(self, x, y, z, t): 91 | return self.send_command(f'{{"T":1041,"x":{x},"y":{y},"z":{z},"t":{t}}}') 92 | 93 | def cmd_servo_rad_feedback(self): 94 | return self.send_command('{"T":105}') 95 | 96 | def cmd_eoat_hand_ctrl(self, cmd, spd, acc): 97 | return self.send_command(f'{{"T":106,"cmd":{cmd},"spd":{spd},"acc":{acc}}}') 98 | 99 | def cmd_single_joint_angle(self, joint, angle, spd, acc): 100 | return self.send_command(f'{{"T":121,"joint":{joint},"angle":{angle},"spd":{spd},"acc":{acc}}}') 101 | 102 | def cmd_joints_angle_ctrl(self, b, s, e, h, spd, acc): 103 | return self.send_command(f'{{"T":122,"b":{b},"s":{s},"e":{e},"h":{h},"spd":{spd},"acc":{acc}}}') 104 | 105 | def cmd_constant_ctrl(self, m, axis, cmd, spd): 106 | return self.send_command(f'{{"T":123,"m":{m},"axis":{axis},"cmd":{cmd},"spd":{spd}}}') 107 | 108 | def cmd_delay_millis(self, cmd): 109 | return self.send_command(f'{{"T":111,"cmd":{cmd}}}') 110 | 111 | # EOAT Control 112 | def cmd_eoat_type(self, mode): 113 | return self.send_command(f'{{"T":1,"mode":{mode}}}') 114 | 115 | def cmd_config_eoat(self, pos, ea, eb): 116 | return self.send_command(f'{{"T":2,"pos":{pos},"ea":{ea},"eb":{eb}}}') 117 | 118 | def cmd_eoat_grab_torque(self, tor): 119 | return self.send_command(f'{{"T":107,"tor":{tor}}}') 120 | 121 | # Joints PID Control 122 | def cmd_set_joint_pid(self, joint, p, i): 123 | return self.send_command(f'{{"T":108,"joint":{joint},"p":{p},"i":{i}}}') 124 | 125 | def cmd_reset_pid(self): 126 | return self.send_command('{"T":109}') 127 | 128 | # Mission & Steps Edit 129 | def cmd_create_mission(self, name, intro): 130 | return self.send_command(f'{{"T":220,"name":"{name}","intro":"{intro}"}}') 131 | 132 | def cmd_mission_content(self, name): 133 | return self.send_command(f'{{"T":221,"name":"{name}"}}') 134 | 135 | def cmd_append_step_json(self, name, step): 136 | return self.send_command(f'{{"T":222,"name":"{name}","step":"{step}"}}') 137 | 138 | def cmd_replace_step_json(self, name, step_num, step): 139 | return self.send_command(f'{{"T":228,"name":"{name}","stepNum":{step_num},"step":"{step}"}}') 140 | 141 | # File System Control 142 | def cmd_scan_files(self): 143 | return self.send_command('{"T":200}') 144 | 145 | def cmd_create_file(self, name, content): 146 | return self.send_command(f'{{"T":201,"name":"{name}","content":"{content}"}}') 147 | 148 | def cmd_read_file(self, name): 149 | return self.send_command(f'{{"T":202,"name":"{name}"}}') 150 | 151 | def cmd_delete_file(self, name): 152 | return self.send_command(f'{{"T":203,"name":"{name}"}}') 153 | 154 | def cmd_append_line(self, name, content): 155 | return self.send_command(f'{{"T":204,"name":"{name}","content":"{content}"}}') 156 | 157 | # Switch Control 158 | def cmd_switch_ctrl(self, pwm_a, pwm_b): 159 | return self.send_command(f'{{"T":113,"pwm_a":{pwm_a},"pwm_b":{pwm_b}}}') 160 | 161 | def cmd_light_ctrl(self, led): 162 | return self.send_command(f'{{"T":114,"led":{led}}}') 163 | 164 | def cmd_switch_off(self): 165 | return self.send_command('{"T":115}') 166 | 167 | # ESP32 Settings 168 | def cmd_reboot(self): 169 | return self.send_command('{"T":600}') 170 | 171 | def cmd_free_flash_space(self): 172 | return self.send_command('{"T":601}') 173 | 174 | def cmd_boot_mission_info(self): 175 | return self.send_command('{"T":602}') 176 | 177 | def cmd_reset_boot_mission(self): 178 | return self.send_command('{"T":603}') 179 | 180 | def cmd_nvs_clear(self): 181 | return self.send_command('{"T":604}') 182 | 183 | def cmd_info_print(self, cmd): 184 | return self.send_command(f'{{"T":605,"cmd":{cmd}}}') 185 | 186 | def do_some_crazy_move(self, radius=None, speed=0.5, acceleration=0.5): 187 | """ 188 | Moves the arm in a crazy move if not used the correct args 189 | 190 | Args: 191 | radius (float, optional): The radius of the circle in meters or units. 192 | Defaults to current position if not provided. 193 | speed (float, optional): The speed of the motion. Defaults to 0.5. 194 | acceleration (float, optional): The acceleration for the motion. Defaults to 0.5. 195 | """ 196 | 197 | # Fetch current position if radius is not provided 198 | if radius is None: 199 | # Assuming self.cmd_servo_rad_feedback() fetches current position in [x, y, z, t] 200 | current_position = self.cmd_servo_rad_feedback() 201 | if isinstance(current_position, str): # If response is a string, parse it 202 | current_position = eval(current_position) # Replace eval with a proper parser in production 203 | radius = current_position.get('radius', 1) # Default to 1 if radius isn't provided 204 | 205 | # Break the circle into segments 206 | segments = 36 # Adjust for smoother or coarser movement 207 | angle_increment = 2 * math.pi / segments 208 | 209 | for i in range(segments + 1): # +1 to complete the circle 210 | angle = i * angle_increment 211 | x = radius * math.cos(angle) 212 | y = radius * math.sin(angle) 213 | z = 0 # Assuming z stays constant 214 | t = angle # Assuming t aligns with the angle of rotation 215 | self.cmd_xyzt_goal_ctrl(x, y, z, t, speed) 216 | 217 | def open_jaw(self, open_cmd=1.0, speed=0.5, acceleration=0.5): 218 | """ 219 | Opens the jaw. 220 | 221 | Args: 222 | open_cmd (float, optional): Command value to open the jaw. Defaults to 1.0. 223 | speed (float, optional): Speed of the jaw movement. Defaults to 0.5. 224 | acceleration (float, optional): Acceleration of the jaw movement. Defaults to 0.5. 225 | """ 226 | self.cmd_eoat_hand_ctrl(open_cmd, speed, acceleration) 227 | print(f"Jaw opened with command: {open_cmd}") 228 | 229 | def close_jaw(self, close_cmd=0.0, speed=0.5, acceleration=0.5): 230 | """ 231 | Closes the jaw. 232 | 233 | Args: 234 | close_cmd (float, optional): Command value to close the jaw. Defaults to 0.0. 235 | speed (float, optional): Speed of the jaw movement. Defaults to 0.5. 236 | acceleration (float, optional): Acceleration of the jaw movement. Defaults to 0.5. 237 | """ 238 | self.cmd_eoat_hand_ctrl(close_cmd, speed, acceleration) 239 | print(f"Jaw closed with command: {close_cmd}") 240 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /APIs/python/Unmanned_Ground_Vehicles/waveshare/ugvcontroller.py: -------------------------------------------------------------------------------- 1 | # flake8: noqa: E501 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | import requests 16 | import subprocess 17 | import sys 18 | 19 | 20 | class UGVController: 21 | """ 22 | This code is all about talking to a robot car (called a UGV, or Unmanned Ground Vehicle). 23 | 24 | It supports basic wheel movement, independent wheel control (if the robot supports it), ROS-based velocity control, 25 | motor PID configuration, and now movement commands for turning, moving backward, and forward. 26 | """ 27 | 28 | def __init__(self, ssid="UGV", password="12345678", ip="192.168.4.1", interface_name=None): 29 | """ 30 | Initialize the UGV controller. 31 | 32 | Args: 33 | ssid (str): The Wi-Fi SSID (default: 'UGV'). 34 | password (str): The Wi-Fi password (default: '12345678'). 35 | ip (str): The rover's IP address (default: '192.168.4.1'). 36 | interface_name (str): Optional wireless interface name (e.g., 'wlan0'). 37 | """ 38 | self.ssid = ssid 39 | self.password = password 40 | self.ip = ip 41 | self.interface_name = interface_name or "wlp9s0" 42 | 43 | def connect_to_wifi(self): 44 | """ 45 | Connect to the Wi-Fi network using nmcli. 46 | 47 | Raises: 48 | SystemExit: If the Wi-Fi connection fails or nmcli is not installed. 49 | """ 50 | print(f"Connecting to Wi-Fi network '{self.ssid}' using interface '{self.interface_name}'...") 51 | try: 52 | command = [ 53 | "nmcli", "connection", "add", "type", "wifi", "ifname", self.interface_name, 54 | "con-name", "UGVConnection", "ssid", self.ssid, 55 | "wifi-sec.key-mgmt", "wpa-psk", "wifi-sec.psk", self.password 56 | ] 57 | subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, check=True) 58 | 59 | activate_command = ["nmcli", "connection", "up", "UGVConnection"] 60 | result = subprocess.run(activate_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) 61 | 62 | if result.returncode == 0: 63 | print(f"Successfully connected to Wi-Fi network '{self.ssid}'.") 64 | else: 65 | print(f"Failed to activate Wi-Fi connection: {result.stderr.strip()}") 66 | sys.exit(1) 67 | 68 | except subprocess.CalledProcessError as e: 69 | print(f"Error creating or activating Wi-Fi connection: {e.stderr.strip()}") 70 | sys.exit(1) 71 | except FileNotFoundError: 72 | print("Error: nmcli is not installed. Please install NetworkManager CLI tools.") 73 | sys.exit(1) 74 | except Exception as e: 75 | print(f"An unexpected error occurred: {e}") 76 | sys.exit(1) 77 | 78 | def move_forward_6wheels(self, left_front=0.5, left_middle=0.5, left_rear=0.5, 79 | right_front=0.5, right_middle=0.5, right_rear=0.5): 80 | """ 81 | ** Not sure if supported by vendor, need to be tested ** 82 | 83 | Move all six wheels forward with individually specified speeds using T: 13. 84 | 85 | Args: 86 | left_front (float): Speed for the front left wheel (-1.0 to 1.0). 87 | left_middle (float): Speed for the middle left wheel (-1.0 to 1.0). 88 | left_rear (float): Speed for the rear left wheel (-1.0 to 1.0). 89 | right_front (float): Speed for the front right wheel (-1.0 to 1.0). 90 | right_middle (float): Speed for the middle right wheel (-1.0 to 1.0). 91 | right_rear (float): Speed for the rear right wheel (-1.0 to 1.0). 92 | 93 | Returns: 94 | str: Response from the rover. 95 | 96 | "T": 2: Configure the motor's PID parameters (Looks like it's not supported by the hardware) 97 | """ 98 | json_data = { 99 | "T": 2, 100 | "LF": left_front, 101 | "LM": left_middle, 102 | "LR": left_rear, 103 | "RF": right_front, 104 | "RM": right_middle, 105 | "RR": right_rear 106 | } 107 | return self.send_json_command(json_data) 108 | 109 | def send_json_command(self, json_data): 110 | """ 111 | Send a JSON command to the rover. 112 | 113 | Args: 114 | json_data (dict): The JSON command to send. 115 | 116 | Returns: 117 | str: The response text from the rover. 118 | 119 | Raises: 120 | RequestException: If there is a communication error with the rover. 121 | """ 122 | try: 123 | url = f"http://{self.ip}/js?json={json_data}" 124 | response = requests.get(url) 125 | print(f"Response: {response.text}") 126 | return response.text 127 | except requests.RequestException as e: 128 | print(f"Error communicating with the rover: {e}") 129 | return None 130 | 131 | def move(self, left_speed, right_speed): 132 | """ 133 | Control left and right wheels together. 134 | 135 | Args: 136 | left_speed (float): Speed for the left wheels (-1.0 to 1.0). 137 | right_speed (float): Speed for the right wheels (-1.0 to 1.0). 138 | 139 | Returns: 140 | str: Response from the rover. 141 | 142 | "T": 1: Control left and right wheels. (at the same time) 143 | """ 144 | json_data = {"T": 1, "L": left_speed, "R": right_speed} 145 | return self.send_json_command(json_data) 146 | 147 | def move_individual_wheels(self, left_front, left_rear, right_front, right_rear): 148 | """ 149 | Control each wheel independently. 150 | 151 | Args: 152 | left_front (float): Speed for the front left wheel (-1.0 to 1.0). 153 | left_rear (float): Speed for the rear left wheel (-1.0 to 1.0). 154 | right_front (float): Speed for the front right wheel (-1.0 to 1.0). 155 | right_rear (float): Speed for the rear right wheel (-1.0 to 1.0). 156 | 157 | Returns: 158 | str: Response from the rover. 159 | 160 | "T": 2: Configure the motor's PID parameters (Looks like it's not supported by the hardware) 161 | """ 162 | json_data = { 163 | "T": 2, "LF": left_front, "LR": left_rear, "RF": right_front, "RR": right_rear 164 | } 165 | return self.send_json_command(json_data) 166 | 167 | def move_right(self, speed=0.5): 168 | """ 169 | Turn the robot to the right by slowing down the right wheels. 170 | 171 | Args: 172 | speed (float): The speed for the left wheels (-1.0 to 1.0). 173 | Default is 0.5 for smooth turning. 174 | 175 | Returns: 176 | str: Response from the rover. 177 | """ 178 | print("Turning right...") 179 | return self.move(left_speed=speed, right_speed=speed * 0.5) 180 | 181 | def move_left(self, speed=0.5): 182 | """ 183 | Turn the robot to the left by slowing down the left wheels. 184 | 185 | Args: 186 | speed (float): The speed for the right wheels (-1.0 to 1.0). 187 | Default is 0.5 for smooth turning. 188 | 189 | Returns: 190 | str: Response from the rover. 191 | """ 192 | print("Turning left...") 193 | return self.move(left_speed=speed * 0.5, right_speed=speed) 194 | 195 | def move_backwards(self, speed=0.5): 196 | """ 197 | Move the robot backwards by setting negative speeds for both wheels. 198 | 199 | Args: 200 | speed (float): The speed for both wheels (0.0 to 1.0). 201 | Default is 0.5 for smooth reverse movement. 202 | 203 | Returns: 204 | str: Response from the rover. 205 | """ 206 | print("Moving backwards...") 207 | return self.move(left_speed=-speed, right_speed=-speed) 208 | 209 | def cmd_ros_control(self, linear_velocity, angular_velocity): 210 | """ 211 | Control the robot using ROS-style velocity commands. 212 | 213 | Args: 214 | linear_velocity (float): The moving linear velocity in m/s (meters per second). 215 | angular_velocity (float): The steering angular velocity in rad/s (radians per second). 216 | 217 | 218 | Keep in mind: 219 | - Linear velocity: How fast the robot should move forward or backward. 220 | - Positive Values: Move forward. 221 | - Negative Values: Move backward. 222 | 223 | Example(s): 224 | - linear_velocity = 0.5: The robot moves forward at 0.5 m/s. 225 | - linear_velocity = -0.3: The robot moves backward at 0.3 m/s. 226 | 227 | - Angular velocity: How fast the robot should turn (rotate) left or right. 228 | - angular_velocity is mesasured by radians per second (rad/s). (A full circle is 2π radians or about 6.28 radians.) 229 | - Positive Values: Turn right (clockwise). 230 | - Negative Values: Turn left (counter-clockwise). 231 | 232 | Example(s): 233 | - angular_velocity = 0.2: The robot slowly turns to the right. 234 | - angular_velocity = -0.5: The robot turns to the left more sharply. 235 | 236 | Returns: 237 | str: Response from the rover. 238 | 239 | "T": 13: ROS-style control for linear and angular velocities. 240 | """ 241 | json_data = {"T": 13, "X": linear_velocity, "Z": angular_velocity} 242 | return self.send_json_command(json_data) 243 | 244 | def set_motor_pid(self, p_coefficient, i_coefficient, d_coefficient, windup_limit=255): 245 | """ 246 | Configure the motor PID values. 247 | 248 | What is PID Control? 249 | PID control is like having a robot "driver" that continuously checks if the motor is doing 250 | what it’s supposed to and makes corrections to keep it on track. 251 | 252 | For example: 253 | 254 | You want the motor to spin at 50 RPM, but due to friction or other factors, it’s spinning at 45 RPM. 255 | A PID controller adjusts the motor's power to get it back to 50 RPM. 256 | 257 | 258 | Args: 259 | p_coefficient (int): Proportional coefficient. 260 | i_coefficient (int): Integral coefficient. 261 | d_coefficient (int): Differential coefficient. 262 | windup_limit (int): Windup limit for the PID controller (default: 255). 263 | 264 | p_coefficient (Proportional coefficient): 265 | This controls how strongly the system reacts to the current error. 266 | If the motor is 10 RPM too slow, the proportional term says, "Let me add more power to fix it right now." 267 | The larger the p_coefficient, the stronger the reaction. But if it’s too large, the system might 268 | overreact and cause instability (e.g., oscillating speeds). 269 | 270 | i_coefficient (Integral coefficient): 271 | This looks at the history of the error over time and tries to fix any lingering issues. 272 | For example, if the motor has been consistently 2 RPM too slow, the integral term will keep track of this 273 | "cumulative error" and gradually adjust the power to eliminate it. 274 | The larger the i_coefficient, the more strongly the controller tries to correct long-term errors. 275 | However, if it’s too large, it may cause the system to overcompensate, leading to instability. 276 | 277 | d_coefficient (Derivative coefficient): 278 | This predicts how the error is changing and adjusts to prevent overshooting or instability. 279 | For example, if the motor is speeding up too fast and might overshoot the target RPM, the derivative 280 | term will slow it down slightly. The larger the d_coefficient, the more cautious the controller is 281 | about rapid changes. If it’s too large, the system may become too sluggish and fail to respond quickly to changes. 282 | 283 | windup_limit (Windup limit for the PID controller): 284 | The windup limit prevents the integral term from accumulating too much error over time. 285 | Why is this important? If the motor is stuck and can’t move for some reason, the integral term might keep "remembering" 286 | the large error and increase the power endlessly. This is called integral windup, and it can make the system unstable. 287 | The windup_limit sets a cap on how much correction the integral term can apply, ensuring the system stays stable. 288 | 289 | Default Value: 290 | The default value is 255, meaning the maximum allowed correction is limited to 255. 291 | 292 | Returns: 293 | str: Response from the rover. 294 | 295 | "T": 2: Configure the motor's PID parameters. 296 | """ 297 | json_data = { 298 | "T": 2, "P": p_coefficient, "I": i_coefficient, 299 | "D": d_coefficient, "L": windup_limit 300 | } 301 | return self.send_json_command(json_data) 302 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Table of Contents 2 | 3 | 1. [About](#about) 4 | 2. [Building the Space Distro](#building-the-space-distro) 5 | 2.1. [Ensure the image base is fetched](#ensure-the-image-base-is-fetched) 6 | 2.2. [Install virt-install and virt-viewer](#install-virt-install-and-virt-viewer) 7 | 2.3. [Create the output directory](#create-the-output-directory) 8 | 2.4. [Install and start libvirt](#install-and-start-libvirt) 9 | 2.5. [Run Podman to create the Virtual Machine](#run-podman-to-create-the-virtual-machine) 10 | 2.6. [Visualize the Virtual Machine with virsh console](#visualize-the-virtual-machine-with-virsh-console) 11 | 3. [Model Rockets](#model-rockets) 12 | 3.1. [Why Model Rockets](#why-model-rockets) 13 | 3.2. [Models for Testing](#models-for-testing) 14 | 3.3. [Whats required to make it work](#whats-required-to-make-it-work) 15 | 3.4. [Engines](#engines) 16 | 4. [Useful Commands](#useful-commands) 17 | 4.1. [Domain Information](#domain-information) 18 | 4.2. [Domain Network Information](#domain-network-information) 19 | 4.3. [Connecting via SSH to the Virtual Machine](#connecting-via-ssh-to-the-virtual-machine) 20 | 5. [Resources](#resources) 21 | 22 | 23 | ## About 24 | ### Space Grade Linux Description 25 | 26 | **Space Grade Linux** is an advanced Linux-based operating system designed to meet the rigorous demands of aerospace, satellite, and other high-reliability environments. It integrates cutting-edge technologies and robust security features to ensure dependable performance in harsh and mission-critical scenarios. Built with an emphasis on modularity, flexibility, and compliance with industry standards, Space Grade Linux is tailored for applications requiring fault tolerance, low latency, and real-time capabilities. 27 | 28 | Key features include: 29 | 30 | 1. **Hardened Security**: Implements robust security mechanisms, including SELinux, mandatory access controls, and containerized workloads to protect against vulnerabilities and ensure data integrity. 31 | 32 | 2. **Real-Time Capabilities**: Optimized kernel configurations enable deterministic real-time processing, vital for controlling spacecraft systems, satellite communications, and aerospace-grade robotics. 33 | 34 | 3. **Lightweight Design**: Minimalist yet scalable, Space Grade Linux operates efficiently on resource-constrained devices while offering adaptability for high-performance hardware. 35 | 36 | 4. **Virtualization Support**: Provides extensive support for virtualization technologies, enabling the simulation and deployment of multiple isolated environments for testing and operations. 37 | 38 | 5. **Containerized Workflows**: Leverages containerization tools such as Podman for secure and efficient deployment of modular applications, supporting rapid updates and rollbacks. 39 | 40 | 6. **Resilience and Fault Tolerance**: Equipped with monitoring, logging, and recovery mechanisms to ensure continued operation in the event of hardware or software failures. 41 | 42 | 7. **Standards Compliance**: Adheres to open-source standards and industry protocols, fostering interoperability with aerospace and automotive ecosystems. 43 | 44 | Space Grade Linux empowers engineers, researchers, and organizations to build reliable, scalable, and secure systems for use in space exploration, defense, and aerospace industries. Its robust feature set and adaptability make it an ideal choice for applications ranging from satellite payload management to unmanned aerial vehicles and beyond. 45 | 46 | ## Building the space distro 47 | 48 | See [src/README.md](src/README.md) 49 | 50 | ## Model Rockets 51 | 52 | Model rockets are small, powered rockets designed for recreational, educational, and hobby use. 53 | 54 | ### Why Model Rockets 55 | Model rockets are an excellent and cost-effective alternative to using full-scale rockets for demonstrations and testing because of their small size, lower cost, and simplicity in setup and operation. Here’s why they are particularly suitable. 56 | 57 | ### Whats required to make it work 58 | 59 | A rocket, engine, launchpad, recovery wadding and parachute. If you are starting and have tidy budget look for Beginner model kit and A8-3 Engine. The beginner kits usually contain Launch pads, a kit to build rocket and parachute. However, if you don't have time to build a rocket, buy one already assembled. 60 | 61 | ### Models for Testing 62 | 63 | - [Estes 1441 Journey Launch Set Beginner Model Kit](https://www.amazon.com/gp/product/B01I8VBUVK/ref=ppx_yo_dt_b_search_asin_title?ie=UTF8&psc=1) 64 |

65 | Estes 1441 66 |

67 | 68 | - [Estes Tandem-X Launch Set](https://www.amazon.com/gp/product/B002VLP67S/ref=ppx_yo_dt_b_search_asin_title?ie=UTF8&psc=1) 69 |

70 | Estes Tandem-x Launch Set 71 |

72 | 73 | - [Estes 2206 NASA SLS Flying Model Rocket Kit](https://www.amazon.com/gp/product/B09JB8KD6K/ref=ppx_yo_dt_b_search_asin_title?ie=UTF8&psc=1) 74 |

75 | Estes SLS 76 |

77 | 78 | - [Estes Saturn V 1:200 Scale](https://www.amazon.com/gp/product/B07QT4MVB6/ref=ppx_yo_dt_b_search_asin_title?ie=UTF8&th=1) 79 |

80 | Estes Saturn V 81 |

82 | 83 | - [Estes 009991 Space Shuttle Model Rocket](https://www.amazon.com/gp/product/B0D2S1WXF3/ref=ppx_yo_dt_b_search_asin_title?ie=UTF8&psc=1) 84 |

85 | Space Shuttle Model 86 |

87 | 88 | - [Estes Blue Origin New Shepard 2198](https://www.amazon.com/gp/product/B09CHH8QKX/ref=ppx_yo_dt_b_search_asin_title?ie=UTF8&psc=1) 89 |

90 | Blue Origin 91 |

92 | 93 | - [Recovery Wadding](https://www.amazon.com/gp/product/B09WZQWD14/ref=ppx_yo_dt_b_search_asin_title?ie=UTF8&psc=1) 94 |

95 | Recovery Wadding 96 |

97 | 98 | - [Rocket Camera - Estes Universal Astrocam HD Rocket Camera 2208](https://www.amazon.com/gp/product/B09QVCP57H/ref=ppx_yo_dt_b_search_asin_title?ie=UTF8&psc=1) 99 |

100 | Rocket Camera 101 |

102 | 103 | ### **1. Cost Savings** 104 | - **Material Costs**: Model rockets are made of inexpensive materials like cardboard, balsa wood, and plastic, while original rockets use high-grade metals, composites, and advanced electronics that are costly to manufacture. 105 | - **Propulsion Systems**: Model rockets use small, affordable solid rocket engines that cost a few dollars, compared to the multi-million-dollar engines on full-scale rockets. 106 | - **Reusable Parts**: With proper recovery systems (e.g., parachutes), many parts of a model rocket can be reused, reducing recurring costs. 107 | 108 | ### **2. Scalability for Demonstration** 109 | - **Scaled-Down Simulations**: Model rockets are a scaled-down representation of full-size rockets, making them ideal for demonstrating concepts like: 110 | - Aerodynamic design. 111 | - Stability and control mechanisms. 112 | - Staging and propulsion systems. 113 | - **Prototyping and Iteration**: Changes to designs can be tested rapidly with model rockets without the need for costly full-scale prototypes. 114 | 115 | ### **3. Safe and Practical Testing** 116 | - **Controlled Environment**: Model rockets can be launched in smaller, controlled environments like fields, requiring less infrastructure than full-scale rocket testing. 117 | - **Safety**: Their size and lightweight materials make them safer to use in demonstrations or educational settings. 118 | - **Regulated Engines**: Model rocket engines are designed to be safe and manageable, unlike full-scale engines that require extensive safety precautions and specialized facilities. 119 | 120 | ### **4. Versatility for Different Demonstrations** 121 | - **Aerodynamic Testing**: Demonstrate airflow, stability, and drag reduction techniques using various nose cone and fin designs. 122 | - **Recovery Systems**: Test parachute or streamer recovery mechanisms for safety and reusability. 123 | - **Payload Integration**: Showcase payload deployment or sensor testing using scaled-down prototypes of full-size equipment. 124 | - **Staging Demonstrations**: Simulate multi-stage rockets to explain how boosters separate and ignite. 125 | 126 | ### **5. Educational and Public Outreach** 127 | - **Simplified Concepts**: Model rockets are an accessible way to teach the principles of rocketry, such as thrust, gravity, and trajectory, without overwhelming costs or risks. 128 | - **Engaging Visuals**: Their launches are visually engaging, making them perfect for demonstrations in classrooms, public science fairs, or promotional events. 129 | - **Hands-On Experience**: Participants can actively engage in building and launching model rockets, fostering greater understanding and enthusiasm for aerospace engineering. 130 | 131 | Using model rockets allows teams to validate ideas, refine designs, and conduct compelling demonstrations at a fraction of the cost and risk of full-scale rockets. They offer flexibility to tailor the demonstration to specific needs while being highly scalable and efficient. 132 | 133 | ### Engines 134 | The **Estes rocket engines** are categorized by a system of letters and numbers that indicate the engine's total impulse, average thrust, and delay time before deploying the recovery system. Here’s what each part of the engine code means: 135 | 136 | ### Breakdown of the Code: 137 | 1. **First Letter (A, B, C, E)**: 138 | Indicates the total impulse (power) of the engine, measured in Newton-seconds. Each successive letter roughly doubles the total impulse: 139 | - **A**: 2.5 N·s 140 | - **B**: 5.0 N·s 141 | - **C**: 10.0 N·s 142 | - **E**: 40.0 N·s 143 | 144 | Higher letters result in greater thrust and altitude potential. 145 | 146 | 2. **First Number (4, 6, 12)**: 147 | Indicates the average thrust in Newtons. Higher numbers provide a stronger push, which is better for heavier rockets. 148 | 149 | 3. **Second Number (3, 4, 5, 0)**: 150 | Indicates the delay in seconds before the ejection charge fires (used for deploying parachutes or other recovery systems). 151 | - **0** indicates a booster engine with no delay or recovery charge; it's meant to stage another engine or burn out. 152 | 153 | --- 154 | 155 | ### Comparing the Engines: 156 | #### **A8-3** 157 | - **Impulse**: Low (A-level, 2.5 N·s). 158 | - **Thrust**: 8 N average. 159 | - **Delay**: 3 seconds. 160 | - Best for small, lightweight rockets; reaches moderate altitudes (~100-200 feet). The delay gives time for the rocket to coast to apogee before deploying recovery. 161 | 162 | #### **B4-4** 163 | - **Impulse**: Medium (B-level, 5.0 N·s). 164 | - **Thrust**: 4 N average. 165 | - **Delay**: 4 seconds. 166 | - Suitable for slightly larger rockets or lighter ones for greater altitudes (~200-400 feet). The delay matches a slightly higher apogee. 167 | 168 | #### **C6-5** 169 | - **Impulse**: High (C-level, 10.0 N·s). 170 | - **Thrust**: 6 N average. 171 | - **Delay**: 5 seconds. 172 | - Higher power for larger rockets or very lightweight rockets for extreme altitudes (~600-1200 feet). The delay suits higher flight paths. 173 | 174 | #### **E12-0** 175 | - **Impulse**: Very high (E-level, 40.0 N·s). 176 | - **Thrust**: 12 N average. 177 | - **Delay**: None (0 indicates it's a booster engine). 178 | - Designed for multi-stage rockets, as it ignites another engine after burnout. Not for single-stage recovery systems. 179 | 180 | --- 181 | 182 | ### Key Differences: 183 | 1. **Total Power**: The higher the letter, the more powerful the engine. 184 | 2. **Thrust**: The first number determines how much "push" the engine provides. 185 | 3. **Delay**: Determines when the recovery system activates (if it does). Engines with "0" are booster stages. 186 | 187 | --- 188 | 189 | ### Which to Use? 190 | - **A8-3**: Best for beginners or lightweight, low-altitude flights. 191 | - **B4-4**: Intermediate power for medium rockets. 192 | - **C6-5**: Higher altitude or larger rocket flights. 193 | - **E12-0**: Multi-stage rockets needing a powerful booster. 194 | 195 | Always match the engine to your rocket’s weight, stability, and design specifications, and check the recommended engines for your model. 196 | 197 | ## Useful commands 198 | 199 | ### List all vms 200 | 201 | ```console 202 | sudo virsh list # list active VMs 203 | sudo virsh list --all # list non active VMs as well 204 | ``` 205 | 206 | ### Domain information 207 | ```console 208 | root@fedora:~# virsh dominfo fedora-bootc 209 | Id: 6 210 | Name: fedora-bootc 211 | UUID: e62ba8b9-5711-4edf-8ea4-59c604e375f4 212 | OS Type: hvm 213 | State: running 214 | CPU(s): 4 215 | CPU time: 220.8s 216 | Max memory: 4194304 KiB 217 | Used memory: 4194304 KiB 218 | Persistent: yes 219 | Autostart: disable 220 | Managed save: no 221 | Security model: selinux 222 | Security DOI: 0 223 | Security label: system_u:system_r:svirt_tcg_t:s0:c556,c955 (enforcing) 224 | ``` 225 | 226 | ### Domain network information 227 | 228 | ```console 229 | root@fedora:~# virsh domifaddr fedora-bootc 230 | Name MAC address Protocol Address 231 | ------------------------------------------------------------------------------- 232 | vnet2 52:54:00:c4:b1:6d ipv4 192.168.124.55/24 233 | ``` 234 | 235 | ### Connecting via SSH to the Virtual Machine 236 | 237 | ```console 238 | $ ssh 192.168.124.55 -lspace 239 | The authenticity of host '192.168.124.55 (192.168.124.55)' can't be established. 240 | ED25519 key fingerprint is SHA256:PIyFB0BxZ7UR2o/5n+WyHR7d3ZJ8fif5/ZzhuWZ1tLg. 241 | This key is not known by any other names. 242 | Are you sure you want to continue connecting (yes/no/[fingerprint])? yes 243 | Warning: Permanently added '192.168.124.55' (ED25519) to the list of known hosts. 244 | space@192.168.124.55's password: 245 | Last login: Tue Dec 31 23:12:03 2024 246 | [space@localhost ~]$ sudo su - 247 | [space@localhost ~]# 248 | ``` 249 | 250 | ### Exiting virsh console 251 | 252 | Exiting from virsh console using keyboard. 253 | 254 | ```console 255 | Press: Ctrl A and Ctrl ] 256 | ``` 257 | 258 | ## Resources 259 | [bootc: Getting started with bootable containers](https://developers.redhat.com/articles/2024/09/24/bootc-getting-started-bootable-containers#) 260 | [osbuild - bootc-image-builder](https://github.com/osbuild/bootc-image-builder?tab=readme-ov-file) 261 | --------------------------------------------------------------------------------