From d1ac41ad1af12b61da48885f7638afa67b0ebf5c Mon Sep 17 00:00:00 2001
From: "bruno.galdos@rwth-aachen.de" <bruno.galdos@rwth-aachen.de>
Date: Thu, 25 Jul 2024 11:22:45 +0000
Subject: [PATCH] followaypoints

---
 colcon_ws/src/my_bot/CMakeLists.txt           |  33 +++
 colcon_ws/src/my_bot/config/empty.yaml        |   1 +
 colcon_ws/src/my_bot/config/view_bot.rviz     | 204 ++++++++++++++++++
 .../description/gazebo_control_kairos.xacro   |  77 +++++++
 .../src/my_bot/launch/controller_launch.py    |  65 ++++++
 .../src/my_bot/launch/evaluation_launch.py    |  76 +++++++
 colcon_ws/src/my_bot/package.xml              |  22 ++
 .../evaluation_node_odom_final.py             |  14 +-
 .../my_controller/trial_controller_goal.py    |   4 +-
 .../my_controller/trial_controller_opti.py    |  40 ++--
 .../trial_controller_opti_improved.py         |   4 +-
 .../trial_controller_waypoints.py             | 193 +++++++++++++++++
 colcon_ws/src/my_controller/setup.py          |   1 +
 entrypoint_scripts/entrypoint_controller.sh   |   5 +-
 14 files changed, 706 insertions(+), 33 deletions(-)
 create mode 100644 colcon_ws/src/my_bot/CMakeLists.txt
 create mode 100644 colcon_ws/src/my_bot/config/empty.yaml
 create mode 100644 colcon_ws/src/my_bot/config/view_bot.rviz
 create mode 100644 colcon_ws/src/my_bot/description/gazebo_control_kairos.xacro
 create mode 100644 colcon_ws/src/my_bot/launch/controller_launch.py
 create mode 100644 colcon_ws/src/my_bot/launch/evaluation_launch.py
 create mode 100644 colcon_ws/src/my_bot/package.xml
 create mode 100755 colcon_ws/src/my_controller/my_controller/trial_controller_waypoints.py

diff --git a/colcon_ws/src/my_bot/CMakeLists.txt b/colcon_ws/src/my_bot/CMakeLists.txt
new file mode 100644
index 0000000..03c12dd
--- /dev/null
+++ b/colcon_ws/src/my_bot/CMakeLists.txt
@@ -0,0 +1,33 @@
+cmake_minimum_required(VERSION 3.8)
+project(my_bot)
+
+if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+  add_compile_options(-Wall -Wextra -Wpedantic)
+endif()
+
+# find dependencies
+find_package(ament_cmake REQUIRED)
+# uncomment the following section in order to fill in
+# further dependencies manually.
+# find_package(<dependency> REQUIRED)
+
+install(DIRECTORY 
+  launch 
+  DESTINATION share/${PROJECT_NAME}
+)
+
+
+
+
+install(DIRECTORY 
+  config 
+  DESTINATION share/${PROJECT_NAME}
+)
+
+install(DIRECTORY 
+  description 
+  DESTINATION share/${PROJECT_NAME}
+)
+
+
+ament_package()
diff --git a/colcon_ws/src/my_bot/config/empty.yaml b/colcon_ws/src/my_bot/config/empty.yaml
new file mode 100644
index 0000000..04700ba
--- /dev/null
+++ b/colcon_ws/src/my_bot/config/empty.yaml
@@ -0,0 +1 @@
+# This is an empty file, so that git commits the folder correctly
\ No newline at end of file
diff --git a/colcon_ws/src/my_bot/config/view_bot.rviz b/colcon_ws/src/my_bot/config/view_bot.rviz
new file mode 100644
index 0000000..9b6f19b
--- /dev/null
+++ b/colcon_ws/src/my_bot/config/view_bot.rviz
@@ -0,0 +1,204 @@
+Panels:
+  - Class: rviz_common/Displays
+    Help Height: 78
+    Name: Displays
+    Property Tree Widget:
+      Expanded:
+        - /Global Options1
+        - /Status1
+        - /TF1
+        - /RobotModel1
+        - /RobotModel1/Status1
+      Splitter Ratio: 0.5
+    Tree Height: 759
+  - Class: rviz_common/Selection
+    Name: Selection
+  - Class: rviz_common/Tool Properties
+    Expanded:
+      - /2D Goal Pose1
+      - /Publish Point1
+    Name: Tool Properties
+    Splitter Ratio: 0.5886790156364441
+  - Class: rviz_common/Views
+    Expanded:
+      - /Current View1
+    Name: Views
+    Splitter Ratio: 0.5
+Visualization Manager:
+  Class: ""
+  Displays:
+    - Alpha: 0.5
+      Cell Size: 1
+      Class: rviz_default_plugins/Grid
+      Color: 160; 160; 164
+      Enabled: true
+      Line Style:
+        Line Width: 0.029999999329447746
+        Value: Lines
+      Name: Grid
+      Normal Cell Count: 0
+      Offset:
+        X: 0
+        Y: 0
+        Z: 0
+      Plane: XY
+      Plane Cell Count: 10
+      Reference Frame: <Fixed Frame>
+      Value: true
+    - Class: rviz_default_plugins/TF
+      Enabled: true
+      Frame Timeout: 15
+      Frames:
+        All Enabled: true
+        base_link:
+          Value: true
+        caster_wheel:
+          Value: true
+        chassis:
+          Value: true
+        left_wheel:
+          Value: true
+        right_wheel:
+          Value: true
+      Marker Scale: 1
+      Name: TF
+      Show Arrows: true
+      Show Axes: true
+      Show Names: true
+      Tree:
+        base_link:
+          chassis:
+            caster_wheel:
+              {}
+          left_wheel:
+            {}
+          right_wheel:
+            {}
+      Update Interval: 0
+      Value: true
+    - Alpha: 1
+      Class: rviz_default_plugins/RobotModel
+      Collision Enabled: false
+      Description File: ""
+      Description Source: Topic
+      Description Topic:
+        Depth: 5
+        Durability Policy: Volatile
+        History Policy: Keep Last
+        Reliability Policy: Reliable
+        Value: /robot_description
+      Enabled: true
+      Links:
+        All Links Enabled: true
+        Expand Joint Details: false
+        Expand Link Details: false
+        Expand Tree: false
+        Link Tree Style: Links in Alphabetic Order
+        base_link:
+          Alpha: 1
+          Show Axes: false
+          Show Trail: false
+        caster_wheel:
+          Alpha: 1
+          Show Axes: false
+          Show Trail: false
+          Value: true
+        chassis:
+          Alpha: 1
+          Show Axes: false
+          Show Trail: false
+          Value: true
+        left_wheel:
+          Alpha: 1
+          Show Axes: false
+          Show Trail: false
+          Value: true
+        right_wheel:
+          Alpha: 1
+          Show Axes: false
+          Show Trail: false
+          Value: true
+      Name: RobotModel
+      TF Prefix: ""
+      Update Interval: 0
+      Value: true
+      Visual Enabled: true
+  Enabled: true
+  Global Options:
+    Background Color: 48; 48; 48
+    Fixed Frame: base_link
+    Frame Rate: 30
+  Name: root
+  Tools:
+    - Class: rviz_default_plugins/Interact
+      Hide Inactive Objects: true
+    - Class: rviz_default_plugins/MoveCamera
+    - Class: rviz_default_plugins/Select
+    - Class: rviz_default_plugins/FocusCamera
+    - Class: rviz_default_plugins/Measure
+      Line color: 128; 128; 0
+    - Class: rviz_default_plugins/SetInitialPose
+      Topic:
+        Depth: 5
+        Durability Policy: Volatile
+        History Policy: Keep Last
+        Reliability Policy: Reliable
+        Value: /initialpose
+    - Class: rviz_default_plugins/SetGoal
+      Topic:
+        Depth: 5
+        Durability Policy: Volatile
+        History Policy: Keep Last
+        Reliability Policy: Reliable
+        Value: /goal_pose
+    - Class: rviz_default_plugins/PublishPoint
+      Single click: true
+      Topic:
+        Depth: 5
+        Durability Policy: Volatile
+        History Policy: Keep Last
+        Reliability Policy: Reliable
+        Value: /clicked_point
+  Transformation:
+    Current:
+      Class: rviz_default_plugins/TF
+  Value: true
+  Views:
+    Current:
+      Class: rviz_default_plugins/Orbit
+      Distance: 1.0897012948989868
+      Enable Stereo Rendering:
+        Stereo Eye Separation: 0.05999999865889549
+        Stereo Focal Distance: 1
+        Swap Stereo Eyes: false
+        Value: false
+      Focal Point:
+        X: 0
+        Y: 0
+        Z: 0
+      Focal Shape Fixed Size: true
+      Focal Shape Size: 0.05000000074505806
+      Invert Z Axis: false
+      Name: Current View
+      Near Clip Distance: 0.009999999776482582
+      Pitch: 0.4002038538455963
+      Target Frame: <Fixed Frame>
+      Value: Orbit (rviz)
+      Yaw: 5.888577461242676
+    Saved: ~
+Window Geometry:
+  Displays:
+    collapsed: false
+  Height: 997
+  Hide Left Dock: false
+  Hide Right Dock: false
+  QMainWindow State: 000000ff00000000fd00000004000000000000016a00000386fc0200000008fb0000001200530065006c0065006300740069006f006e00000001e10000009b0000006400fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed000001df00000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c006100790073010000004100000386000000dd00fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261000000010000010f00000386fc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a00560069006500770073010000004100000386000000b000fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e10000019700000003000004420000003efc0100000002fb0000000800540069006d00650100000000000004420000000000000000fb0000000800540069006d00650100000000000004500000000000000000000004fb0000038600000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000
+  Selection:
+    collapsed: false
+  Tool Properties:
+    collapsed: false
+  Views:
+    collapsed: false
+  Width: 1920
+  X: 0
+  Y: 28
diff --git a/colcon_ws/src/my_bot/description/gazebo_control_kairos.xacro b/colcon_ws/src/my_bot/description/gazebo_control_kairos.xacro
new file mode 100644
index 0000000..8e58a46
--- /dev/null
+++ b/colcon_ws/src/my_bot/description/gazebo_control_kairos.xacro
@@ -0,0 +1,77 @@
+<?xml version="1.0"?>
+<robot xmlns:xacro="http://www.ros.org/wiki/xacro">
+
+
+  <!-- ros control plugin-->
+  <xacro:macro name="ros_control">
+    <gazebo>
+      <plugin name="ros_control" filename="libgazebo_ros_control.so">
+        <!--<robotNamespace>/summit_xl</robotNamespace>-->
+		<robotParam>robot_description</robotParam>
+        <controlPeriod>0.001</controlPeriod>
+	    <robotSimType>gazebo_ros_control/DefaultRobotHWSim</robotSimType>
+      </plugin>
+    </gazebo>
+	</xacro:macro>
+	
+	<!-- skid steering plugin 
+    libgazebo_ros_skid_steer_drive plugin was
+   replaced with the libgazebo_ros_diff_drive -->
+	<xacro:macro name="skid_steering" params="broadcastOdomTF prefix">
+    <gazebo>
+      <plugin name="skid_steer_drive_controller" filename="libgazebo_ros_diff_drive.so">
+			<!--<robotNamespace>/summit_xl</robotNamespace>-->
+		    <updateRate>100.0</updateRate>
+		    <leftFrontJoint>${prefix}joint_front_left_wheel</leftFrontJoint>  
+		    <rightFrontJoint>${prefix}joint_front_right_wheel</rightFrontJoint>
+		    <leftRearJoint>${prefix}joint_back_left_wheel</leftRearJoint>
+		    <rightRearJoint>${prefix}joint_back_right_wheel</rightRearJoint>
+		    <!-- wheelSeparation>0.566</wheelSeparation --> <!-- real parameter value -->
+		    <wheelSeparation>1.5</wheelSeparation> <!-- works a bit better in Gazebo -->
+		    <wheelDiameter>0.234</wheelDiameter>
+		    <robotBaseFrame>${prefix}base_footprint</robotBaseFrame>
+		    <torque>50</torque>
+		    <commandTopic>robotnik_base_control/cmd_vel</commandTopic>
+		    <odometryTopic>robotnik_base_control/odom</odometryTopic>
+		    <!--odometryFrame>/odom</odometryFrame-->
+		    <odometryFrame>${prefix}odom</odometryFrame>
+		    <broadcastTF>${broadcastOdomTF}</broadcastTF>
+      </plugin>
+    </gazebo>
+  </xacro:macro>
+  
+  <xacro:macro name="omni_steering" params="prefix publish_tf">
+		<gazebo>
+	    <plugin name="omni_steering" filename="libgazebo_ros_planar_move.so">
+	      <commandTopic>robotnik_base_control/cmd_vel</commandTopic>  
+	      <odometryTopic>robotnik_base_control/odom</odometryTopic>
+	      <odometryFrame>${prefix}odom</odometryFrame>
+	      <odometryRate>50.0</odometryRate>
+	      <robotBaseFrame>${prefix}base_footprint</robotBaseFrame>
+	      <publishTF>${publish_tf}</publishTF>
+	    </plugin>
+	  </gazebo>
+  </xacro:macro>
+<!--<robotNamespace>/summit_xl</robotNamespace>
+  <xacro:macro name="ros_force_based_move" params="publish_tf prefix">
+	  <gazebo>
+		 <plugin name="ros_force_based_move" filename="libgazebo_ros_force_based_move.so">
+			 <commandTopic>robotnik_base_control/cmd_vel</commandTopic>  
+			 <odometryTopic>robotnik_base_control/odom</odometryTopic>
+	         <odometryFrame>${prefix}odom</odometryFrame>
+			 <yaw_velocity_p_gain>10000.0</yaw_velocity_p_gain>
+			 <x_velocity_p_gain>10000.0</x_velocity_p_gain>
+			 <y_velocity_p_gain>10000.0</y_velocity_p_gain>
+			 <robotBaseFrame>${prefix}base_footprint</robotBaseFrame>
+			 <odometryRate>50.0</odometryRate>
+			 <publishOdometryTf>${publish_tf}</publishOdometryTf>
+		 </plugin>
+	  </gazebo>
+  </xacro:macro>
+-->
+  <gazebo reference="base_footprint">
+    <material>Gazebo/Green</material>
+  </gazebo>
+  
+
+</robot>
\ No newline at end of file
diff --git a/colcon_ws/src/my_bot/launch/controller_launch.py b/colcon_ws/src/my_bot/launch/controller_launch.py
new file mode 100644
index 0000000..a56a3eb
--- /dev/null
+++ b/colcon_ws/src/my_bot/launch/controller_launch.py
@@ -0,0 +1,65 @@
+import os
+from ament_index_python.packages import get_package_share_directory
+
+from launch import LaunchDescription
+from launch.actions import DeclareLaunchArgument
+from launch.substitutions import LaunchConfiguration
+from launch_ros.actions import Node
+import logging
+
+def generate_launch_description():
+    try:
+        return LaunchDescription([
+
+            DeclareLaunchArgument(
+                'x', default_value='1.0', description='X coordinate of the goal pose'
+            ),
+            DeclareLaunchArgument(
+                'y', default_value='1.0', description='Y coordinate of the goal pose'
+            ),
+            DeclareLaunchArgument(
+                'theta', default_value='0.0', description='Theta of the goal pose'
+            ),
+            DeclareLaunchArgument(
+                'velocity', default_value='0.2', description='Velocity of the goal pose'
+            ),
+            DeclareLaunchArgument(
+                'waypoints', 
+                default_value='['
+                    '2.9, -0.08, 0.0, '
+                    '4.9, -0.08, 0.0, '
+                    '4.9, 1.92, 0.0, '
+                    '2.9, 1.92, 0.0'
+                ']',
+
+            #    default_value='['
+            #        '2.9, -0.08, 0.0, '
+            #        '4.9, 1.92, 0.0, '
+            #        '4.9, -0.08, 0.0, '
+            #        '2.9, 1.92, 0.0'
+            #    ']',
+                description='Waypoints to follow (flat list)'
+            ),
+            DeclareLaunchArgument(
+                'waypoint_velocity', default_value='0.2', description='Velocity for following waypoints'
+            ),
+
+            Node(
+                package='my_controller',
+                executable='trial_controller_waypoints',
+                name='trial_controller_node',
+                output='screen',
+                parameters=[
+                    {'x': LaunchConfiguration('x')},
+                    {'y': LaunchConfiguration('y')},
+                    {'theta': LaunchConfiguration('theta')},
+                    {'velocity': LaunchConfiguration('velocity')},
+                    {'waypoints': LaunchConfiguration('waypoints')},
+                    {'waypoint_velocity': LaunchConfiguration('waypoint_velocity')}
+                ]
+            )
+
+        ])
+    except Exception as e: 
+        logging.error("An error occurred: " + str(e))
+        raise
diff --git a/colcon_ws/src/my_bot/launch/evaluation_launch.py b/colcon_ws/src/my_bot/launch/evaluation_launch.py
new file mode 100644
index 0000000..2ee1278
--- /dev/null
+++ b/colcon_ws/src/my_bot/launch/evaluation_launch.py
@@ -0,0 +1,76 @@
+import os
+from ament_index_python.packages import get_package_share_directory
+
+from launch import LaunchDescription
+from launch.actions import IncludeLaunchDescription
+from launch.launch_description_sources import PythonLaunchDescriptionSource
+from launch_ros.actions import Node
+
+def generate_launch_description():
+    # Include the robot_state_publisher launch file, provided by our own package. Force sim time to be enabled
+    # !!! MAKE SURE YOU SET THE PACKAGE NAME CORRECTLY !!!
+    package_name = 'my_controller'  # <--- CHANGE ME
+    
+    # Run the spawner node from the gazebo_ros package. The entity name doesn't really matter if you only have a single robot.
+    evaluation_slam = Node(
+        package=package_name,
+        executable='evaluation_node_slam',
+        output='screen'
+    )
+    
+    evaluation_odom = Node(
+        package=package_name,
+        executable='evaluation_node_odom',
+        output='screen'
+    )
+    """
+    trial_controller_1 = Node(
+        package=package_name,
+        executable='trial_controller',
+        name='trial_controller_1',  # Fixed the name
+        parameters=[
+            
+            {'goal_pose': {'x': -2.0, 'y': -1.5, 'theta': 0.0}}],
+        output='screen'
+    )
+    
+    trial_controller_2 = Node(
+        package=package_name,
+        executable='trial_controller',
+        name='trial_controller_2',  # Fixed the name
+        parameters=[{'goal_pose': {'x': 2.5, 'y': -2.0, 'theta': 0.0}}],
+        output='screen'
+    )
+    
+    
+    trial_controller_3 = Node(
+        package=package_name,
+        executable='trial_controller',
+        name='trial_controller_3',  # Fixed the name
+        
+        #parameters=[{'goal_pose': {'x': 2.0, 'y': 3.0, 'theta': 0.0}}],
+        output='screen'
+    )
+     """
+    # Code for delaying a node (I haven't tested how effective it is)
+    # First add the below lines to imports
+    # from launch.actions import RegisterEventHandler
+    # from launch.event_handlers import OnProcessExit
+    #
+    # Then add the following below the current diff_drive_spawner
+    # delayed_diff_drive_spawner = RegisterEventHandler(
+    #     event_handler=OnProcessExit(
+    #         target_action=spawn_entity,
+    #         on_exit=[diff_drive_spawner],
+    #     )
+    # )
+    #
+    # Replace the diff_drive_spawner in the final return with delayed_diff_drive_spawner
+
+    # Launch them all!
+    return LaunchDescription([
+
+       
+        evaluation_odom,
+        evaluation_slam
+    ])
diff --git a/colcon_ws/src/my_bot/package.xml b/colcon_ws/src/my_bot/package.xml
new file mode 100644
index 0000000..b9d41c4
--- /dev/null
+++ b/colcon_ws/src/my_bot/package.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
+<package format="3">
+  <name>my_bot</name>
+  <version>0.0.0</version>
+  <description>TODO: Package description</description>
+  <maintainer email="athena@todo.todo">athena</maintainer>
+  <license>TODO: License declaration</license>
+
+  <buildtool_depend>ament_cmake</buildtool_depend>
+
+  <exec_depend>robot_state_publisher</exec_depend>
+
+  <exec_depend>my_controller</exec_depend>
+
+  <test_depend>ament_lint_auto</test_depend>
+  <test_depend>ament_lint_common</test_depend>
+
+  <export>
+    <build_type>ament_cmake</build_type>
+  </export>
+</package>
diff --git a/colcon_ws/src/my_controller/my_controller/evaluation_node_odom_final.py b/colcon_ws/src/my_controller/my_controller/evaluation_node_odom_final.py
index 5482557..1367e4b 100755
--- a/colcon_ws/src/my_controller/my_controller/evaluation_node_odom_final.py
+++ b/colcon_ws/src/my_controller/my_controller/evaluation_node_odom_final.py
@@ -17,18 +17,18 @@ class EvaluateNode(Node):
     def __init__(self):
         super().__init__('optitrack_subscriber')
 
-        self.subscription = self.create_subscription(
-            RigidBodyStamped, 
-            '/optitrack_multiplexer_node/rigid_body/kairosAB', 
-            self.pose_callback, 
-            10)
-
         #self.subscription = self.create_subscription(
         #    RigidBodyStamped, 
-        #    '/optitrack_multiplexer_node/rigid_body/BenchmarkArtefact', 
+        #    '/optitrack_multiplexer_node/rigid_body/kairosAB', 
         #    self.pose_callback, 
         #    10)
 
+        self.subscription = self.create_subscription(
+            RigidBodyStamped, 
+            '/optitrack_multiplexer_node/rigid_body/BenchmarkArtefact', 
+            self.pose_callback, 
+            10)
+
 
         self.get_logger().info(f"taking metrics from optitrack")
         self.csv_file=None
diff --git a/colcon_ws/src/my_controller/my_controller/trial_controller_goal.py b/colcon_ws/src/my_controller/my_controller/trial_controller_goal.py
index 8ae49d7..0278ce1 100755
--- a/colcon_ws/src/my_controller/my_controller/trial_controller_goal.py
+++ b/colcon_ws/src/my_controller/my_controller/trial_controller_goal.py
@@ -23,8 +23,8 @@ class MoveRobotNode(Node):
         #self.subscription = self.create_subscription(Odometry, '/diff_cont/odom', self.odom_callback, 10)    #differential
         #self.subscription = self.create_subscription(Odometry, '/robot/robotnik_base_control/odom', self.odom_callback, 10)   #for kairos simulation
         #self.subscription = self.create_subscription(Odometry, '/kairosAB/robotnik_base_control/odom', self.odom_callback, 10)   #for kairos AB real
-        self.subscription = self.create_subscription(RigidBodyStamped,'/optitrack_multiplexer_node/rigid_body/BenchmarkArtefact',self.odom_callback,10) 
-        #self.subscription = self.create_subscription(RigidBodyStamped,'/optitrack_multiplexer_node/rigid_body/kairosAB',self.odom_callback,10) 
+        #self.subscription = self.create_subscription(RigidBodyStamped,'/optitrack_multiplexer_node/rigid_body/BenchmarkArtefact',self.odom_callback,10) 
+        self.subscription = self.create_subscription(RigidBodyStamped,'/optitrack_multiplexer_node/rigid_body/kairosAB',self.odom_callback,10) 
         
         self.current_pose = [0.02, 0.02, 0.02]
         #self.current_pose =self.get_start_pose()
diff --git a/colcon_ws/src/my_controller/my_controller/trial_controller_opti.py b/colcon_ws/src/my_controller/my_controller/trial_controller_opti.py
index 47f6bc3..faa9911 100755
--- a/colcon_ws/src/my_controller/my_controller/trial_controller_opti.py
+++ b/colcon_ws/src/my_controller/my_controller/trial_controller_opti.py
@@ -1,5 +1,5 @@
 #!/usr/bin/env python3
-
+import time
 import rclpy
 from rclpy.node import Node
 from geometry_msgs.msg import Twist
@@ -29,12 +29,12 @@ class MoveRobotNode(Node):
         #self.publisher_ = self.create_publisher(Twist, '/diff_cont/cmd_vel_unstamped', 10)  #for differential robot
         #self.publisher_ = self.create_publisher(Twist, '/cmd_vel', 10)                      #normal msg topic
         #self.publisher_ = self.create_publisher(Twist, 'robot/cmd_vel', 10)                  #for kairos simulation
-        self.publisher_ = self.create_publisher(Twist, 'kairosAB/cmd_vel', 10)                  #for kairosAA real
+        self.publisher_ = self.create_publisher(Twist, 'kairosAA/cmd_vel', 10)                  #for kairosAA real
         #self.publisher_ = self.create_publisher(Twist, 'kairosAB/cmd_vel', 10)                  #for kairosAB real
         #self.subscription = self.create_subscription(Odometry, '/odom', self.odom_callback, 10)     #normal
         #self.subscription = self.create_subscription(Odometry, '/diff_cont/odom', self.odom_callback, 10)    #differential
 
-        self.subscription = self.create_subscription(RigidBodyStamped,'/optitrack_multiplexer_node/rigid_body/kairosAB',self.odom_callback,10)
+        self.subscription = self.create_subscription(RigidBodyStamped,'/optitrack_multiplexer_node/rigid_body/kairosAA',self.odom_callback,10)
         #self.subscription = self.create_subscription(RigidBodyStamped,'/optitrack_multiplexer_node/rigid_body/kairosAB',self.odom_callback,10) 
         
         #self.subscription = self.create_subscription(Odometry, '/robot/robotnik_base_control/odom', self.odom_callback, 10)   #for kairos simulation
@@ -46,8 +46,11 @@ class MoveRobotNode(Node):
 
         #self.current_pose =  [0.02, 0.02, 0.02]
         #self.goal_pose =  [0.05, 0.05, 0.05]
-        self.current_pose =  [0.0002, 0.0002, 0.002]
-        self.goal_pose =  [1.5003, 1.5003, 0.005]
+        self.current_pose =  [-1.92, -2.9, 0.02]
+        #self.current_pose =  [0.0002, 0.0002, 0.02] original
+        self.goal_pose =  [-2.14, -6.5, 0.05] 
+        #self.goal_pose =  [1.9603, 1.96003, 0.05] original
+        
     
 
     def pose_callback(self,msg):
@@ -75,15 +78,10 @@ class MoveRobotNode(Node):
   
 
 
-
+    #move it gheers
     #function for moving the robot 
-    """
-    def move_robot(self, velocity, obstacle):
-
-     
-        obstacle_border = obstacle['border']
-    """
-    def move_robot(self, goal_pose_2,velocity):
+   
+    def move_robot(self,velocity):
 
     
 
@@ -94,7 +92,7 @@ class MoveRobotNode(Node):
         # Stage 1: Move the robot forward towards the goal
         distance = (error_x**2 + error_y**2)**0.5
 
-        while distance >= 1.40:  #previous 0.01
+        while distance >= 1.7:  #previous 0.6 original
 
 
 
@@ -124,7 +122,7 @@ class MoveRobotNode(Node):
             msg.linear.x = linear_velocity_x
             msg.linear.y= linear_velocity_y
 
-            if distance < 1.40:  # threshold original 0.01
+            if distance < 1.7:  # threshold original 0.6 
      
                 print("first stage reached END") # stop rotating
 
@@ -142,8 +140,9 @@ class MoveRobotNode(Node):
         
 
 
-
+        """
         # Stage 2: Rotate the robot to the goal orientation
+        time.sleep(1)
         error_theta_final = goal_pose_2 - self.current_pose[2]
         error_theta_final = (error_theta_final + math.pi) % (2 * math.pi) - math.pi  # normalize to [-pi, pi]
         while abs(error_theta_final) > 0.01:  # adjust threshold
@@ -170,7 +169,7 @@ class MoveRobotNode(Node):
             self.publisher_.publish(msg)
 
             rclpy.spin_once(self)    
- 
+            """
 
 
      
@@ -181,14 +180,15 @@ def main(args=None):
 
 
     
-    goal_pose_2=float(input("Enter goal theta from -π to π : "))
+    #goal_pose_2=float(input("Enter goal theta from -π to π : "))
     velocity = float(input("Enter velocity: "))  
 
-    obstacle = {'border': [(1, 1), (1, 2), (2, 2), (2, 1)]}
+    #obstacle = {'border': [(1, 1), (1, 2), (2, 2), (2, 1)]}
 
     
      
-    move_robot_node.move_robot(goal_pose_2,velocity)
+    #move_robot_node.move_robot(goal_pose_2,velocity)
+    move_robot_node.move_robot(velocity)
     #move_robot_node.move_robot(velocity,obstacle)
 
     rclpy.spin(move_robot_node)
diff --git a/colcon_ws/src/my_controller/my_controller/trial_controller_opti_improved.py b/colcon_ws/src/my_controller/my_controller/trial_controller_opti_improved.py
index 46b5dc8..9556d2f 100755
--- a/colcon_ws/src/my_controller/my_controller/trial_controller_opti_improved.py
+++ b/colcon_ws/src/my_controller/my_controller/trial_controller_opti_improved.py
@@ -29,12 +29,12 @@ class MoveRobotNode(Node):
         #self.publisher_ = self.create_publisher(Twist, '/diff_cont/cmd_vel_unstamped', 10)  #for differential robot
         #self.publisher_ = self.create_publisher(Twist, '/cmd_vel', 10)                      #normal msg topic
         #self.publisher_ = self.create_publisher(Twist, 'robot/cmd_vel', 10)                  #for kairos simulation
-        self.publisher_ = self.create_publisher(Twist, 'kairosAB/cmd_vel', 10)                  #for kairosAA real
+        self.publisher_ = self.create_publisher(Twist, 'kairosAA/cmd_vel', 10)                  #for kairosAA real
         #self.publisher_ = self.create_publisher(Twist, 'kairosAB/cmd_vel', 10)                  #for kairosAB real
         #self.subscription = self.create_subscription(Odometry, '/odom', self.odom_callback, 10)     #normal
         #self.subscription = self.create_subscription(Odometry, '/diff_cont/odom', self.odom_callback, 10)    #differential
 
-        self.subscription = self.create_subscription(RigidBodyStamped,'/optitrack_multiplexer_node/rigid_body/kairosAB',self.odom_callback,10)
+        self.subscription = self.create_subscription(RigidBodyStamped,'/optitrack_multiplexer_node/rigid_body/kairosAA',self.odom_callback,10)
         #self.subscription = self.create_subscription(RigidBodyStamped,'/optitrack_multiplexer_node/rigid_body/kairosAB',self.odom_callback,10) 
         
         #self.subscription = self.create_subscription(Odometry, '/robot/robotnik_base_control/odom', self.odom_callback, 10)   #for kairos simulation
diff --git a/colcon_ws/src/my_controller/my_controller/trial_controller_waypoints.py b/colcon_ws/src/my_controller/my_controller/trial_controller_waypoints.py
new file mode 100755
index 0000000..46af3d8
--- /dev/null
+++ b/colcon_ws/src/my_controller/my_controller/trial_controller_waypoints.py
@@ -0,0 +1,193 @@
+#!/usr/bin/env python3
+
+import rclpy
+from rclpy.node import Node
+from geometry_msgs.msg import Twist
+from nav_msgs.msg import Odometry
+
+from scipy.spatial.transform import Rotation as R
+import math
+from optitrack_multiplexer_ros2_msgs.msg import RigidBodyStamped
+import sys
+from functools import partial
+class MoveRobotNode(Node):
+
+    
+    def __init__(self):
+        super().__init__('move_robot_node')
+        self.declare_parameter('x', 0.0)
+        self.declare_parameter('y', 0.0)
+        self.declare_parameter('theta', 0.0)
+        self.declare_parameter('velocity', 0.0)
+        
+        self.declare_parameter('waypoints', [
+
+            2.9, 0.32, 0.0,  \
+            4.5, 0.32, 0.0, \
+            4.5, 1.92, 0.0, \
+            2.9, 1.92, 0.0
+        ])
+        self.declare_parameter('waypoint_velocity', 0.2)
+
+        #self.publisher_ = self.create_publisher(Twist, '/diff_cont/cmd_vel_unstamped', 10)  #for differential robot
+        #self.publisher_ = self.create_publisher(Twist, '/cmd_vel', 10)                      #normal msg topic
+        #self.publisher_ = self.create_publisher(Twist, 'robot/cmd_vel', 10)                  #for kairos simulation
+        self.publisher_ = self.create_publisher(Twist, 'kairosAA/cmd_vel', 10)                  #for kairosAB real
+        #self.subscription = self.create_subscription(Odometry, '/odom', self.odom_callback, 10)     #normal
+        #self.subscription = self.create_subscription(Odometry, '/diff_cont/odom', self.odom_callback, 10)    #differential
+        #self.subscription = self.create_subscription(Odometry, '/robot/robotnik_base_control/odom', self.odom_callback, 10)   #for kairos simulation
+        #self.subscription = self.create_subscription(Odometry, '/kairosAB/robotnik_base_control/odom', self.odom_callback, 10)   #for kairos AB real
+        #self.subscription = self.create_subscription(RigidBodyStamped,'/optitrack_multiplexer_node/rigid_body/BenchmarkArtefact',self.odom_callback,10) 
+        self.subscription = self.create_subscription(RigidBodyStamped,'/optitrack_multiplexer_node/rigid_body/kairosAA',self.odom_callback,10) 
+        
+        self.current_pose = [0.02, 0.02, 0.02]
+        #self.current_pose =self.get_start_pose()
+
+    """       
+    def get_start_pose(self):
+  
+        start_x = -float(input("Enter start y in optitrack coords: "))
+        start_y = -float(input("Enter start x in optitrack coords: "))
+        self.start_theta = float( input("Enter start theta from -π to π :"))
+        return [start_x, start_y, self.start_theta]
+    """
+    
+    def follow_waypoints(self):
+        waypoints_param = self.get_parameter('waypoints').get_parameter_value().double_array_value
+        velocity = self.get_parameter('waypoint_velocity').get_parameter_value().double_value
+        
+        # Reshape flat list into list of [x, y, theta] lists
+        waypoints = [waypoints_param[i:i + 3] for i in range(0, len(waypoints_param), 3)]
+        
+        for waypoint in waypoints:
+            self.get_logger().info(f'Moving to waypoint: {waypoint}')
+            
+            self.move_robot(waypoint, velocity)
+            # Simulate waiting for robot to reach the waypoint (you might want to implement proper feedback)
+
+            rclpy.spin_once(self, timeout_sec=6)
+
+        self.get_logger().info('Finished following waypoints')
+
+
+    def odom_callback(self, msg):
+
+        self.current_pose[0] = msg.rigid_body.pose.position.y
+        self.current_pose[1] = -msg.rigid_body.pose.position.x
+        orientation_q = msg.rigid_body.pose.orientation
+        r = R.from_quat([orientation_q.q_x, orientation_q.q_y, orientation_q.q_z, orientation_q.q_w])
+        _, _, roll = r.as_euler('XYZ')
+
+        self.current_pose[2] = roll
+
+    #function for moving the robot 
+    def move_robot(self, goal_pose, velocity):
+
+        error_x = goal_pose[0] - self.current_pose[0]
+        error_y = goal_pose[1] - self.current_pose[1]
+    
+
+        # Stage 1: Move the robot forward towards the goal
+        distance = (error_x**2 + error_y**2)**0.5
+
+        while distance >= 0.03:
+            error_x = goal_pose[0] - self.current_pose[0]
+            error_y = goal_pose[1] - self.current_pose[1]
+            distance = (error_x**2 + error_y**2)**0.5
+            
+            print("Current pose x,y,theta: ", self.current_pose)
+            print("distance left", distance)    
+            # direction towards the goal
+            direction_to_goal = [goal_pose[0] - self.current_pose[0], goal_pose[1] - self.current_pose[1]]
+
+            # current direction of the robot based on start_theta pose 
+            #current_direction=[math.cos(self.start_theta), math.sin(self.start_theta)]
+            current_direction = [math.cos(self.current_pose[2]), math.sin(self.current_pose[2])]
+
+            # angle between the current direction and the direction to the goal
+            angle_to_goal = math.atan2(direction_to_goal[1], direction_to_goal[0]) - math.atan2(current_direction[1], current_direction[0])
+
+            # Normalize the angle to the range [-pi, pi] since gazebo is in that way
+            angle_to_goal = (angle_to_goal + math.pi) % (2 * math.pi) - math.pi
+
+            linear_velocity_x = velocity * math.cos(angle_to_goal)
+            linear_velocity_y = velocity * math.sin(angle_to_goal)
+
+            msg = Twist()
+            msg.linear.x = linear_velocity_x
+            msg.linear.y= linear_velocity_y
+            if distance < 0.03:  # threshold if the robot is close enough to the target orientation
+     
+                print("first stage reached END") # stop rotating
+
+                stop_msg = Twist()
+                stop_msg.linear.x = 0.0
+                stop_msg.linear.y =0.0
+                stop_msg.angular.z =0.0
+                self.publisher_.publish(stop_msg)
+                break
+
+
+
+            self.publisher_.publish(msg)
+
+            rclpy.spin_once(self)
+
+        # Stage 2: Rotate the robot to the goal orientation
+        error_theta_final = goal_pose[2] - self.current_pose[2]
+        error_theta_final = (error_theta_final + math.pi) % (2 * math.pi) - math.pi  # normalize to [-pi, pi]
+        while abs(error_theta_final) > 0.01:  # adjust threshold
+
+            angular_velocity = velocity * error_theta_final 
+            print("error_theta_is",error_theta_final)
+            error_theta_final = goal_pose[2] - self.current_pose[2]
+            error_theta_final = (error_theta_final + math.pi) % (2 * math.pi) - math.pi
+            if abs(error_theta_final) < 0.01:  # if the robot is close enough to the target orientation
+
+                print("goal orientation reached END") # stop rotating
+                        # create and publish Twist message to stop the robot
+                stop_msg = Twist()
+                stop_msg.linear.x = 0.0
+                stop_msg.linear.y = 0.0
+                stop_msg.angular.z =0.0
+                self.publisher_.publish(stop_msg)
+                            
+                
+                break
+            
+            msg = Twist()
+            msg.angular.z = angular_velocity
+            self.publisher_.publish(msg)
+
+            rclpy.spin_once(self)    
+ 
+
+
+     
+def main(args=None):
+    rclpy.init(args=args)
+    
+    move_robot_node = MoveRobotNode()
+
+    #goal_pose = [-float(input("Enter goal y in optitrack coords: ")), -float(input("Enter goal x in optitrack coords: ")), float(input("Enter goal theta from -π to π : "))]
+    #velocity = float(input("Enter velocity: "))   
+    
+    goal_pose = [
+    move_robot_node.get_parameter('x').get_parameter_value().double_value,
+    move_robot_node.get_parameter('y').get_parameter_value().double_value,
+    move_robot_node.get_parameter('theta').get_parameter_value().double_value
+    ]
+    velocity = move_robot_node.get_parameter('velocity').get_parameter_value().double_value
+    
+    
+    #move_robot_node.move_robot(goal_pose, velocity)
+    move_robot_node.follow_waypoints()
+
+    rclpy.spin(move_robot_node)
+
+    move_robot_node.destroy_node()
+    rclpy.shutdown()
+
+if __name__ == '__main__':
+    main()
+
diff --git a/colcon_ws/src/my_controller/setup.py b/colcon_ws/src/my_controller/setup.py
index 664ce66..95f09f7 100644
--- a/colcon_ws/src/my_controller/setup.py
+++ b/colcon_ws/src/my_controller/setup.py
@@ -27,6 +27,7 @@ setup(
             "trial_controller_opti_improved= my_controller.trial_controller_opti_improved:main",
             "trial_controller_backup_original= my_controller.trial_controller_backup_original:main",
             "trial_controller_goal= my_controller.trial_controller_goal:main",
+            "trial_controller_waypoints= my_controller.trial_controller_waypoints:main",
             "evaluation_node=my_controller.evaluation_node:main",
             "simplenode=my_controller.simplenode:main",
             "node_markers=my_controller.node_markers:main",
diff --git a/entrypoint_scripts/entrypoint_controller.sh b/entrypoint_scripts/entrypoint_controller.sh
index 8523635..a1dfa2d 100644
--- a/entrypoint_scripts/entrypoint_controller.sh
+++ b/entrypoint_scripts/entrypoint_controller.sh
@@ -19,8 +19,9 @@ source /colcon_ws/install/setup.bash
 #ros2 run my_controller trial_controller_diff_opti
 #ros2 run my_controller trial_controller_diff
 #ros2 run my_controller trial_controller_backup
-#ros2 run my_controller trial_controller_opti
+ros2 run my_controller trial_controller_opti
 #ros2 run my_controller trial_controller_opti_improved
 #ros2 run my_controller trial_controller
-ros2 run my_controller trial_controller_goal
+#ros2 run my_controller trial_controller_goal
+#ros2 launch my_bot controller_launch.py
 #ros2 run my_controller node_markers
-- 
GitLab