finishing iml experiment
This commit is contained in:
parent
d160de1838
commit
a6945ecf92
@ -19,7 +19,7 @@ class DMPNode(Node):
|
|||||||
super().__init__('dmp_node')
|
super().__init__('dmp_node')
|
||||||
self.subscription = self.create_subscription(
|
self.subscription = self.create_subscription(
|
||||||
DMP,
|
DMP,
|
||||||
'franka_iml_experiment/dmps',
|
'franka_iml_experiment/dmp',
|
||||||
self.dmp_callback,
|
self.dmp_callback,
|
||||||
10)
|
10)
|
||||||
self.subscription # prevent unused variable warning
|
self.subscription # prevent unused variable warning
|
||||||
@ -37,7 +37,7 @@ class DMPNode(Node):
|
|||||||
weights = np.vstack((msg.p_x, msg.p_y))
|
weights = np.vstack((msg.p_x, msg.p_y))
|
||||||
|
|
||||||
dmp = pydmps.dmp_discrete.DMPs_discrete(n_dmps=2, n_bfs=nr_bfs, w=weights, y0=start[:2], goal=end[:2])
|
dmp = pydmps.dmp_discrete.DMPs_discrete(n_dmps=2, n_bfs=nr_bfs, w=weights, y0=start[:2], goal=end[:2])
|
||||||
y_track, _, _ = dmp.rollout(tau=time)
|
y_track, _, ddy_track = dmp.rollout(tau=time)
|
||||||
|
|
||||||
pose_msg = PoseArray()
|
pose_msg = PoseArray()
|
||||||
for i in range(y_track.shape[0]):
|
for i in range(y_track.shape[0]):
|
||||||
|
211
franka_iml_experiment/iml_experiment_node.py
Normal file
211
franka_iml_experiment/iml_experiment_node.py
Normal file
@ -0,0 +1,211 @@
|
|||||||
|
import rclpy
|
||||||
|
from rclpy.node import Node
|
||||||
|
from rclpy.callback_groups import ReentrantCallbackGroup
|
||||||
|
|
||||||
|
from std_msgs.msg import Empty
|
||||||
|
from geometry_msgs.msg import PoseArray
|
||||||
|
from geometry_msgs.msg import Pose
|
||||||
|
from active_bo_msgs.msg import DMP
|
||||||
|
from active_bo_msgs.msg import ActiveRLResponse
|
||||||
|
from active_bo_msgs.msg import ActiveRLEvalRequest
|
||||||
|
from active_bo_msgs.msg import ActiveRLEvalResponse
|
||||||
|
|
||||||
|
import pydmps
|
||||||
|
import pydmps.dmp_discrete
|
||||||
|
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
|
||||||
|
class IML_Experiment(Node):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__('iml_node')
|
||||||
|
|
||||||
|
rl_callback_group = ReentrantCallbackGroup()
|
||||||
|
topic_callback_group = ReentrantCallbackGroup()
|
||||||
|
|
||||||
|
self.traj_pub = self.create_publisher(PoseArray,
|
||||||
|
'moveit_interface/task_space_trajectory',
|
||||||
|
10,
|
||||||
|
callback_group=rl_callback_group)
|
||||||
|
|
||||||
|
self.exec_pub = self.create_publisher(Empty,
|
||||||
|
'moveit_interface/execute',
|
||||||
|
10)
|
||||||
|
|
||||||
|
self.rl_subscription = self.create_subscription(DMP,
|
||||||
|
'active_rl_request',
|
||||||
|
self.dmp_callback,
|
||||||
|
10,
|
||||||
|
callback_group=rl_callback_group)
|
||||||
|
|
||||||
|
self.active_rl_pub = self.create_publisher(ActiveRLResponse,
|
||||||
|
'active_rl_response',
|
||||||
|
1,
|
||||||
|
callback_group=rl_callback_group)
|
||||||
|
|
||||||
|
# interactive part
|
||||||
|
self.eval_pub = self.create_publisher(ActiveRLEvalRequest,
|
||||||
|
'active_rl_eval_request',
|
||||||
|
1,
|
||||||
|
callback_group=topic_callback_group)
|
||||||
|
self.eval_sub = self.create_subscription(ActiveRLEvalResponse,
|
||||||
|
'active_rl_eval_response',
|
||||||
|
self.rl_eval_callback,
|
||||||
|
1,
|
||||||
|
callback_group=topic_callback_group)
|
||||||
|
|
||||||
|
# Reward constants
|
||||||
|
self.distance_pen = -0.1
|
||||||
|
self.accel_pen = -0.1
|
||||||
|
self.time_pen = -1
|
||||||
|
self.zone_pen = -20
|
||||||
|
self.goal_rew = 10
|
||||||
|
|
||||||
|
# BO parameters
|
||||||
|
self.start = np.array([0.5, -0.3])
|
||||||
|
self.end = np.array([0.5, -0.3])
|
||||||
|
self.time = 10
|
||||||
|
self.nr_dim = 2
|
||||||
|
self.nr_bfs = None
|
||||||
|
self.nr_steps = None
|
||||||
|
self.weight_preference = None
|
||||||
|
|
||||||
|
def dmp_callback(self, msg):
|
||||||
|
start = self.start
|
||||||
|
end = np.array([0.5, -0.3])
|
||||||
|
self.nr_bfs = msg.nr_bfs
|
||||||
|
self.nr_steps = msg.nr_steps
|
||||||
|
interactive_run = msg.interactive_run
|
||||||
|
weights = np.vstack((msg.p_x, msg.p_y))
|
||||||
|
|
||||||
|
dmp = pydmps.dmp_discrete.DMPs_discrete(n_dmps=self.nr_dim, n_bfs=self.nr_bfs, w=weights, y0=start, goal=end,
|
||||||
|
dt=1 / self.nr_steps, )
|
||||||
|
y_track, _, ddy_track = dmp.rollout(tau=self.time)
|
||||||
|
|
||||||
|
if interactive_run != 0:
|
||||||
|
|
||||||
|
reward, not_perform = self.compute_reward(y_track, ddy_track, self.nr_steps)
|
||||||
|
|
||||||
|
if interactive_run == 1 and not not_perform:
|
||||||
|
pose_msg = PoseArray()
|
||||||
|
for i in range(y_track.shape[0]):
|
||||||
|
pose = Pose()
|
||||||
|
pose.position.x = y_track[i, 0]
|
||||||
|
pose.position.y = y_track[i, 1]
|
||||||
|
pose.position.z = 0.15
|
||||||
|
pose.orientation.x = 1
|
||||||
|
pose.orientation.y = 0
|
||||||
|
pose.orientation.z = 0
|
||||||
|
pose.orientation.w = 0
|
||||||
|
pose_msg.poses.append(pose)
|
||||||
|
|
||||||
|
self.traj_pub.publish(pose_msg)
|
||||||
|
# self.exec_pub.publish(Empty())
|
||||||
|
|
||||||
|
rl_response = ActiveRLResponse()
|
||||||
|
rl_response.weights = msg.p_x + msg.p_y
|
||||||
|
rl_response.reward = reward
|
||||||
|
rl_response.final_step = self.nr_steps
|
||||||
|
if self.weight_preference is None:
|
||||||
|
weight_preference = [False] * len(self.nr_bfs * 2)
|
||||||
|
else:
|
||||||
|
weight_preference = self.weight_preference
|
||||||
|
|
||||||
|
rl_response.weight_preference = weight_preference
|
||||||
|
|
||||||
|
self.active_rl_pub.publish(rl_response)
|
||||||
|
|
||||||
|
|
||||||
|
else:
|
||||||
|
eval_msg = ActiveRLEvalRequest()
|
||||||
|
eval_msg.weights = msg.p_x + msg.p_y
|
||||||
|
eval_msg.policy = y_track[:, 0].tolist() + y_track[:, 1] .tolist()
|
||||||
|
eval_msg.nr_steps = self.nr_steps
|
||||||
|
eval_msg.nr_weights = self.nr_bfs
|
||||||
|
|
||||||
|
self.eval_pub.publish(eval_msg)
|
||||||
|
|
||||||
|
def rl_eval_callback(self, msg):
|
||||||
|
eval_weights = msg.weights.reshape((self.nr_bfs, self.nr_dim), order='F')
|
||||||
|
self.weight_preference = msg.weight_preference
|
||||||
|
|
||||||
|
dmp = pydmps.dmp_discrete.DMPs_discrete(n_dmps=self.nr_dim, n_bfs=self.nr_bfs, w=eval_weights, y0=self.start,
|
||||||
|
goal=self.end, dt=1 / self.nr_steps, )
|
||||||
|
y_track, _, ddy_track = dmp.rollout(tau=self.time)
|
||||||
|
|
||||||
|
self.get_logger().info('Active RL Eval: Responded!')
|
||||||
|
|
||||||
|
reward, not_perform = self.compute_reward(y_track, ddy_track, self.nr_steps)
|
||||||
|
|
||||||
|
if not not_perform:
|
||||||
|
pose_msg = PoseArray()
|
||||||
|
for i in range(y_track.shape[0]):
|
||||||
|
pose = Pose()
|
||||||
|
pose.position.x = y_track[i, 0]
|
||||||
|
pose.position.y = y_track[i, 1]
|
||||||
|
pose.position.z = 0.15
|
||||||
|
pose.orientation.x = 1
|
||||||
|
pose.orientation.y = 0
|
||||||
|
pose.orientation.z = 0
|
||||||
|
pose.orientation.w = 0
|
||||||
|
pose_msg.poses.append(pose)
|
||||||
|
|
||||||
|
self.traj_pub.publish(pose_msg)
|
||||||
|
|
||||||
|
def compute_reward(self, y_track, ddy_track, time):
|
||||||
|
square_center = np.array([0.5, 0.0])
|
||||||
|
square_half_side = 0.1 # half of the side length
|
||||||
|
circle_center = np.array([0.5, 0.5])
|
||||||
|
circle_radius = 0.02
|
||||||
|
|
||||||
|
# 1. Check if any (x,y) position is within the square
|
||||||
|
within_square = np.any(
|
||||||
|
(y_track[:, 0] > square_center[0] - square_half_side) &
|
||||||
|
(y_track[:, 0] < square_center[0] + square_half_side) &
|
||||||
|
(y_track[:, 1] > square_center[1] - square_half_side) &
|
||||||
|
(y_track[:, 1] < square_center[1] + square_half_side)
|
||||||
|
)
|
||||||
|
|
||||||
|
# If the robot moves into the forbidden zone it won't perform trajectory and get penalized
|
||||||
|
if within_square:
|
||||||
|
return self.zone_pen + time * self.time_pen, within_square
|
||||||
|
|
||||||
|
# 2. Check if any (x,y) position is within the circle
|
||||||
|
t = 0
|
||||||
|
for i in range(y_track.shape[0]):
|
||||||
|
distance_to_circle_center = np.linalg.norm(y_track[i, :] - circle_center, axis=1)
|
||||||
|
if distance_to_circle_center < circle_radius:
|
||||||
|
t = i
|
||||||
|
|
||||||
|
y_track = y_track[:t, :]
|
||||||
|
ddy_track = ddy_track[:t, :]
|
||||||
|
|
||||||
|
penalty = t * self.time_pen
|
||||||
|
|
||||||
|
# 3. Compute the Euclidean distance from each (x,y) position to the center of the square
|
||||||
|
distances_to_square_center = np.linalg.norm(y_track - square_center, axis=1)
|
||||||
|
total_distance_norm = np.sum(distances_to_square_center)
|
||||||
|
|
||||||
|
# 1. Compute the norm of each acceleration and sum them up
|
||||||
|
accel_norms = np.linalg.norm(ddy_track, axis=1)
|
||||||
|
total_accel_norm = np.sum(accel_norms)
|
||||||
|
|
||||||
|
penalty += total_distance_norm * self.distance_pen + total_accel_norm * self.accel_pen
|
||||||
|
|
||||||
|
return penalty, within_square
|
||||||
|
|
||||||
|
|
||||||
|
def main(args=None):
|
||||||
|
rclpy.init(args=args)
|
||||||
|
|
||||||
|
dmp_node = IML_Experiment()
|
||||||
|
|
||||||
|
rclpy.spin(dmp_node)
|
||||||
|
|
||||||
|
dmp_node.destroy_node()
|
||||||
|
rclpy.shutdown()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
Loading…
Reference in New Issue
Block a user