Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[New exercise] Added Real Follow Person exercise #2129

Open
wants to merge 18 commits into
base: old_manager
Choose a base branch
from
Open
1 change: 0 additions & 1 deletion academy/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,4 +175,3 @@
)

CORS_ALLOW_CREDENTIALS = True

Binary file modified db.sqlite3
Binary file not shown.
2 changes: 1 addition & 1 deletion exercises/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,4 @@ def context(self):
'indexs': exercise_assets.get('indexs', []),
'statics': exercise_assets.get('statics', [])}

return context
return context
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import os.path
from typing import Callable

from src.manager.libs.applications.compatibility.physical_robot_exercise_wrapper_ros2 import CompatibilityExerciseWrapperRos2


class Exercise(CompatibilityExerciseWrapperRos2):
def __init__(self, circuit: str, update_callback: Callable):
current_path = os.path.dirname(__file__)

super(Exercise, self).__init__(exercise_command=f"{current_path}/../../python_template/ros2_humble/exercise.py 0.0.0.0",
gui_command=f"{current_path}/../../python_template/ros2_humble/gui.py 0.0.0.0 {circuit}",
update_callback=update_callback)
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
from launch import LaunchDescription
from launch_ros.actions import Node
from launch.substitutions import ThisLaunchFileDir
from launch.actions import IncludeLaunchDescription
from launch.launch_description_sources import PythonLaunchDescriptionSource
from ament_index_python.packages import get_package_share_directory
import os

def generate_launch_description():

kobuki_launch_file_path = os.path.join(get_package_share_directory('kobuki_launch'), 'launch')

kobuki_launcher = IncludeLaunchDescription(
PythonLaunchDescriptionSource(
os.path.join(kobuki_launch_file_path, 'kobuki_base.launch.py')
)
)

camera_node = Node(
package='usb_cam',
namespace='camera_node',
executable='usb_cam_node_exe',
name='camera'
)

rplidar_node = Node(
name='rplidar_composition',
package='rplidar_ros',
executable='rplidar_composition',
output='screen',
parameters=[{
'serial_port': '/dev/rplidar',
'serial_baudrate': 115200, # A1 / A2
# 'serial_baudrate': 256000, # A3
'frame_id': 'laser',
'inverted': False,
'angle_compensate': True,
}],
)

# Create the launch description and populate
ld = LaunchDescription()

ld.add_action(kobuki_launcher)
ld.add_action(rplidar_node)
ld.add_action(camera_node)

return ld
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
import time
import threading
import multiprocessing
import sys
from datetime import datetime
import importlib

from user_functions import GUIFunctions, HALFunctions
from console import start_console, close_console
from shared.value import SharedValue

# The brain process class
class BrainProcess(multiprocessing.Process):
def __init__(self, code, exit_signal, stop_signal):
super(BrainProcess, self).__init__()

# Initialize exit signal
self.exit_signal = exit_signal
self.stop_signal = stop_signal

# Function definitions for users to use
self.hal = HALFunctions()
self.gui = GUIFunctions()

# Time variables
self.brain_time_cycle = SharedValue('brain_time_cycle')
self.brain_ideal_cycle = SharedValue('brain_ideal_cycle')
self.iteration_counter = 0

# Get the sequential and iterative code
self.sequential_code = code[0]
self.iterative_code = code[1]

# Function to run to start the process
def run(self):
# Two threads for running and measuring
self.measure_thread = threading.Thread(target=self.measure_frequency)
self.thread = threading.Thread(target=self.process_code)

self.measure_thread.start()
self.thread.start()

print("Brain Process Started!")

self.exit_signal.wait()

# The process function
def process_code(self):
# Redirect information to console
start_console()

# Reference Environment for the exec() function
iterative_code, sequential_code = self.iterative_code, self.sequential_code

# Whatever the code is, first step is to just stop!
self.hal.sendV(0)
self.hal.sendW(0)

# The Python exec function
# Run the sequential part
gui_module, hal_module = self.generate_modules()
reference_environment = {"GUI": gui_module, "HAL": hal_module}
if sequential_code != "":
exec(sequential_code, reference_environment)

# Run the iterative part inside template
# and keep the check for flag
while not self.exit_signal.is_set():
while (self.stop_signal.is_set()):
if (self.exit_signal.is_set()):
break
time.sleep(0.1)

start_time = datetime.now()

# Execute the iterative portion
if iterative_code != "":
exec(iterative_code, reference_environment)

# Template specifics to run!
finish_time = datetime.now()
dt = finish_time - start_time
ms = (dt.days * 24 * 60 * 60 + dt.seconds) * 1000 + dt.microseconds / 1000.0

# Keep updating the iteration counter
if(iterative_code == ""):
self.iteration_counter = 0
else:
self.iteration_counter = self.iteration_counter + 1

# The code should be run for atleast the target time step
# If it's less put to sleep
# If it's more no problem as such, but we can change it!
brain_time_cycle = self.brain_time_cycle.get()
if(ms < brain_time_cycle):
time.sleep((brain_time_cycle - ms) / 1000.0)

close_console()
print("Current Thread Joined!", flush=True)

# Function to generate the modules for use in ACE Editor
def generate_modules(self):
# Define HAL module
hal_module = importlib.util.module_from_spec(importlib.machinery.ModuleSpec("HAL", None))
hal_module.HAL = importlib.util.module_from_spec(importlib.machinery.ModuleSpec("HAL", None))
hal_module.HAL.motors = importlib.util.module_from_spec(importlib.machinery.ModuleSpec("motors", None))

# Add HAL functions
hal_module.HAL.getImage = self.hal.getImage
hal_module.HAL.setV = self.hal.sendV
hal_module.HAL.setW = self.hal.sendW
hal_module.HAL.getLaserData = self.hal.getLaserData
hal_module.HAL.getBoundingBoxes = self.hal.getBoundingBoxes
hal_module.HAL.getPose3d = self.hal.getPose3d

# Define GUI module
gui_module = importlib.util.module_from_spec(importlib.machinery.ModuleSpec("GUI", None))
gui_module.GUI = importlib.util.module_from_spec(importlib.machinery.ModuleSpec("GUI", None))

# Add GUI functions
gui_module.GUI.showImage = self.gui.showImage

# Adding modules to system
# Protip: The names should be different from
# other modules, otherwise some errors
sys.modules["HAL"] = hal_module
sys.modules["GUI"] = gui_module

return gui_module, hal_module

# Function to measure the frequency of iterations
def measure_frequency(self):
previous_time = datetime.now()
# An infinite loop
while not self.exit_signal.is_set():
# Sleep for 2 seconds
time.sleep(2)

# Measure the current time and subtract from the previous time to get real time interval
current_time = datetime.now()
dt = current_time - previous_time
ms = (dt.days * 24 * 60 * 60 + dt.seconds) * 1000 + dt.microseconds / 1000.0
previous_time = current_time

# Get the time period
try:
# Division by zero
self.brain_ideal_cycle.add(ms / self.iteration_counter)
except:
self.brain_ideal_cycle.add(0)

# Reset the counter
self.iteration_counter = 0
Loading