adipu_ws
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -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')())
|
||||
@@ -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')())
|
||||
@@ -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')())
|
||||
@@ -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')())
|
||||
@@ -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')())
|
||||
@@ -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()
|
||||
@@ -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')())
|
||||
@@ -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()
|
||||
@@ -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()
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,2 @@
|
||||
/root/adipu_ws/build/adipu_turtlesim_controller
|
||||
.
|
||||
Reference in New Issue
Block a user