This commit is contained in:
Aditya Pulipaka
2025-04-11 13:23:47 -05:00
parent a8341be7ef
commit 18bbd84e01
1101 changed files with 65981 additions and 0 deletions

View File

@@ -0,0 +1,33 @@
#!/usr/bin/python3
# EASY-INSTALL-ENTRY-SCRIPT: 'adipu-turtlesim-controller','console_scripts','chase_run_node'
import re
import sys
# for compatibility with easy_install; see #2198
__requires__ = 'adipu-turtlesim-controller'
try:
from importlib.metadata import distribution
except ImportError:
try:
from importlib_metadata import distribution
except ImportError:
from pkg_resources import load_entry_point
def importlib_load_entry_point(spec, group, name):
dist_name, _, _ = spec.partition('==')
matches = (
entry_point
for entry_point in distribution(dist_name).entry_points
if entry_point.group == group and entry_point.name == name
)
return next(matches).load()
globals().setdefault('load_entry_point', importlib_load_entry_point)
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(load_entry_point('adipu-turtlesim-controller', 'console_scripts', 'chase_run_node')())

View File

@@ -0,0 +1,33 @@
#!/usr/bin/python3
# EASY-INSTALL-ENTRY-SCRIPT: 'adipu-turtlesim-controller','console_scripts','chaser_flipper'
import re
import sys
# for compatibility with easy_install; see #2198
__requires__ = 'adipu-turtlesim-controller'
try:
from importlib.metadata import distribution
except ImportError:
try:
from importlib_metadata import distribution
except ImportError:
from pkg_resources import load_entry_point
def importlib_load_entry_point(spec, group, name):
dist_name, _, _ = spec.partition('==')
matches = (
entry_point
for entry_point in distribution(dist_name).entry_points
if entry_point.group == group and entry_point.name == name
)
return next(matches).load()
globals().setdefault('load_entry_point', importlib_load_entry_point)
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(load_entry_point('adipu-turtlesim-controller', 'console_scripts', 'chaser_flipper')())

View File

@@ -0,0 +1,33 @@
#!/usr/bin/python3
# EASY-INSTALL-ENTRY-SCRIPT: 'adipu-turtlesim-controller','console_scripts','chaser_flipper_node'
import re
import sys
# for compatibility with easy_install; see #2198
__requires__ = 'adipu-turtlesim-controller'
try:
from importlib.metadata import distribution
except ImportError:
try:
from importlib_metadata import distribution
except ImportError:
from pkg_resources import load_entry_point
def importlib_load_entry_point(spec, group, name):
dist_name, _, _ = spec.partition('==')
matches = (
entry_point
for entry_point in distribution(dist_name).entry_points
if entry_point.group == group and entry_point.name == name
)
return next(matches).load()
globals().setdefault('load_entry_point', importlib_load_entry_point)
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(load_entry_point('adipu-turtlesim-controller', 'console_scripts', 'chaser_flipper_node')())

View File

@@ -0,0 +1,33 @@
#!/usr/bin/python3
# EASY-INSTALL-ENTRY-SCRIPT: 'adipu-turtlesim-controller','console_scripts','chaser_node'
import re
import sys
# for compatibility with easy_install; see #2198
__requires__ = 'adipu-turtlesim-controller'
try:
from importlib.metadata import distribution
except ImportError:
try:
from importlib_metadata import distribution
except ImportError:
from pkg_resources import load_entry_point
def importlib_load_entry_point(spec, group, name):
dist_name, _, _ = spec.partition('==')
matches = (
entry_point
for entry_point in distribution(dist_name).entry_points
if entry_point.group == group and entry_point.name == name
)
return next(matches).load()
globals().setdefault('load_entry_point', importlib_load_entry_point)
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(load_entry_point('adipu-turtlesim-controller', 'console_scripts', 'chaser_node')())

View File

@@ -0,0 +1,33 @@
#!/usr/bin/python3
# EASY-INSTALL-ENTRY-SCRIPT: 'adipu-turtlesim-controller','console_scripts','mouse_follow_node'
import re
import sys
# for compatibility with easy_install; see #2198
__requires__ = 'adipu-turtlesim-controller'
try:
from importlib.metadata import distribution
except ImportError:
try:
from importlib_metadata import distribution
except ImportError:
from pkg_resources import load_entry_point
def importlib_load_entry_point(spec, group, name):
dist_name, _, _ = spec.partition('==')
matches = (
entry_point
for entry_point in distribution(dist_name).entry_points
if entry_point.group == group and entry_point.name == name
)
return next(matches).load()
globals().setdefault('load_entry_point', importlib_load_entry_point)
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(load_entry_point('adipu-turtlesim-controller', 'console_scripts', 'mouse_follow_node')())

View File

@@ -0,0 +1,92 @@
#!/usr/bin/env python3
import rclpy
from rclpy.node import Node
from geometry_msgs.msg import Twist
import tkinter as tk
from std_srvs.srv import Empty
CA = 5
CL = 5
class Turtle1Controller(Node):
def __init__(self):
super().__init__("mouse_follow")
self.create_timer(0.1, self.publish_cmdVel)
self.root = tk.Tk()
self.cmdVelMsg=tk.StringVar()
self.pause_resume_info = tk.StringVar()
self.prStat = "PAUSE"
self.pause_resume_info.set(f"Click anywhere to {self.prStat} turtle1 control, right click to clear drawing")
self.paused = False
self.lin = 0.0
self.ang = 0.0
self.cmdPub = self.create_publisher(Twist, '/turtle1/cmd_vel', 10)
self.root.geometry("500x500")
self.canvas = tk.Canvas(self.root, width=500, height=500)
self.canvas.pack(fill=tk.BOTH, expand=True)
self.canvas.create_line(100, 100, 90, 30, 10, 10, smooth=True, arrow=tk.LAST, width=10, arrowshape=(10, 10, 10))
self.canvas.create_line(100, 400, 90, 470, 10, 490, smooth=True, arrow=tk.LAST, width=10, arrowshape=(10, 10, 10))
self.canvas.create_line(400, 100, 410, 30, 490, 10, smooth=True, arrow=tk.LAST, width=10, arrowshape=(10, 10, 10))
self.canvas.create_line(400, 400, 410, 470, 490, 490, smooth=True, arrow=tk.LAST, width=10, arrowshape=(10, 10, 10))
self.position_label = tk.Label(self.canvas, textvariable=self.cmdVelMsg)
self.position_label.pack(pady=20)
self.pause_resume_label = tk.Label(self.canvas, textvariable=self.pause_resume_info)
self.pause_resume_label.place(relx=0.5, rely=0.5, anchor=tk.CENTER)
self.root.bind('<Motion>', self.motion)
self.root.bind('<Button-1>', self.pauseResume)
self.clear_client = self.create_client(Empty, '/clear')
self.root.bind('<Button-3>', self.clear_background)
def publish_cmdVel(self):
if self.paused:
self.root.update_idletasks()
self.root.update()
return
msg = Twist()
msg.linear.x = self.lin
msg.angular.z = self.ang
self.cmdPub.publish(msg)
self.cmdVelMsg.set(f"lin.x: {self.lin:.2f}, ang.z: {self.ang:.2f}")
self.get_logger().info(f"Command: lin.x={self.lin:.2f}, ang.z={self.ang:.2f}")
self.root.update_idletasks()
self.root.update()
def motion(self, event):
x = self.root.winfo_pointerx() - self.root.winfo_rootx()
y = self.root.winfo_pointery() - self.root.winfo_rooty()
center_x = self.root.winfo_width() // 2
center_y = self.root.winfo_height() // 2
self.ang = CA*(x - center_x) * 2/self.root.winfo_width() # x from -C to C for angular
self.lin = -1*CL*(y - center_y)*2/self.root.winfo_height() # y from -C to C for linear
if self.lin > 0: self.ang *= -1
def pauseResume(self, event):
self.paused = not self.paused
self.prStat = "RESUME" if self.paused else "PAUSE"
self.pause_resume_info.set(f"Click anywhere to {self.prStat} turtle1 control, right click to clear drawing")
msg = Twist()
msg.linear.x = 0.0
msg.angular.z = 0.0
self.cmdPub.publish(msg)
self.get_logger().info("Paused" if self.paused else "Resumed")
def clear_background(self, event):
if not self.clear_client.wait_for_service(timeout_sec=1.0):
self.get_logger().warn('/clear doesn\'t exist yet :(')
return
req = Empty.Request()
asyncreq = self.clear_client.call_async(req)
def main(args=None):
rclpy.init(args=args)
node = Turtle1Controller()
rclpy.spin(node)
rclpy.shutdown()
if __name__=='__main__':
main()

View File

@@ -0,0 +1,33 @@
#!/usr/bin/python3
# EASY-INSTALL-ENTRY-SCRIPT: 'adipu-turtlesim-controller','console_scripts','mouse_test'
import re
import sys
# for compatibility with easy_install; see #2198
__requires__ = 'adipu-turtlesim-controller'
try:
from importlib.metadata import distribution
except ImportError:
try:
from importlib_metadata import distribution
except ImportError:
from pkg_resources import load_entry_point
def importlib_load_entry_point(spec, group, name):
dist_name, _, _ = spec.partition('==')
matches = (
entry_point
for entry_point in distribution(dist_name).entry_points
if entry_point.group == group and entry_point.name == name
)
return next(matches).load()
globals().setdefault('load_entry_point', importlib_load_entry_point)
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(load_entry_point('adipu-turtlesim-controller', 'console_scripts', 'mouse_test')())

View File

@@ -0,0 +1,78 @@
#!/usr/bin/env python3
import rclpy
from rclpy.node import Node
from geometry_msgs.msg import Twist
from turtlesim.msg import Pose
from adipu_turtlesim_controller.msg import Flip
from math import pow, atan2, sqrt, pi, sin, cos
CL = 1
CA = 5
class Turtle2Controller(Node):
def __init__(self):
super().__init__("turtle_chase")
#always have latest data, set queue size to 1
self.turt1poseSub = self.create_subscription(Pose, '/turtle1/pose', self.update_goal, 1)
self.turt2poseSub = self.create_subscription(Pose, '/turtle2/pose', self.update_start, 1)
self.turt2velPub = self.create_publisher(Twist, '/turtle2/cmd_vel', 1)
self.turtFlipSub = self.create_subscription(Flip, '/turtle2/flipper', self.flip, 1)
self.runAway = False
self.create_timer(0.05, self.approach_goal)
self.pose = Pose()
self.goal_pose = Pose()
self.tolerance = 0.1
self.away_thresh = 7
def update_start(self, data):
self.pose = data
self.pose.x = round(self.pose.x, 4)
self.pose.y = round(self.pose.y, 4)
def update_goal(self, data):
self.goal_pose = data
self.goal_pose.x = round(self.goal_pose.x, 4)
self.goal_pose.y = round(self.goal_pose.y, 4)
def flip(self, data):
self.runAway = not self.runAway
def distFromGoal(self):
return sqrt(pow(self.goal_pose.x - self.pose.x, 2)
+ pow(self.goal_pose.y - self.pose.y,
2)) if not self.runAway else self.away_thresh - sqrt(pow(self.goal_pose.x - self.pose.x, 2)
+ pow(self.goal_pose.y - self.pose.y, 2))
def angleFromGoal(self):
return atan2(self.goal_pose.y - self.pose.y,
self.goal_pose.x - self.pose.x) if not self.runAway else pi + atan2(self.goal_pose.y -
self.pose.y, self.goal_pose.x - self.pose.x)
def approach_goal(self):
turt2_cmd = Twist()
dist = self.distFromGoal()
angFromGoal = self.angleFromGoal()
# normalize angle difference, to account for -180 to 180 jump
ang = atan2(sin(angFromGoal - self.pose.theta), cos(angFromGoal - self.pose.theta))
directionalCoeff = 1 - abs(ang)*2/pi # filter movement so it only works constructively to our goal.
if dist >= self.tolerance:
turt2_cmd.linear.x = CL * dist * directionalCoeff
turt2_cmd.angular.z = CA*ang # proportional control, as outlined in https://wiki.ros.org/turtlesim/Tutorials/Go%20to%20Goal
else:
turt2_cmd.linear.x = 0.0
turt2_cmd.angular.z = 0.0
self.turt2velPub.publish(turt2_cmd)
self.get_logger().info(f"command: lin.x={turt2_cmd.linear.x:.2f}, ang.z={turt2_cmd.angular.z:.2f}")
def main(args=None):
rclpy.init(args=args)
node = Turtle2Controller()
rclpy.spin(node)
rclpy.shutdown()
if __name__=='__main__':
main()

View File

@@ -0,0 +1,20 @@
import rclpy
from rclpy.node import Node
from adipu_turtlesim_controller.msg import Flip
class Turtle2Flipper(Node):
def __init__(self):
super().__init__("turtle_flip")
self.flipPub = self.create_publisher(Flip, '/turtle2/flipper', 1)
self.create_timer(10, self.flip)
def flip(self):
msg = Flip()
self.flipPub.publish(msg)
def main(args=None):
rclpy.init(args=args)
node = Turtle2Flipper()
rclpy.spin(node)
rclpy.shutdown()

View File

@@ -0,0 +1,2 @@
/root/adipu_ws/build/adipu_turtlesim_controller
.