Simulate joint trajectory and move gripper interfaces
This commit is contained in:
parent
0545dbcc06
commit
e04361dd8c
122
bt_sim_node.py
122
bt_sim_node.py
@ -6,6 +6,8 @@ import cv_bridge
|
|||||||
import numpy as np
|
import numpy as np
|
||||||
import rospy
|
import rospy
|
||||||
|
|
||||||
|
import control_msgs.msg
|
||||||
|
import controller_manager_msgs.srv
|
||||||
import franka_gripper.msg
|
import franka_gripper.msg
|
||||||
from geometry_msgs.msg import Pose
|
from geometry_msgs.msg import Pose
|
||||||
from sensor_msgs.msg import JointState, Image, CameraInfo
|
from sensor_msgs.msg import JointState, Image, CameraInfo
|
||||||
@ -13,25 +15,25 @@ import std_srvs.srv
|
|||||||
|
|
||||||
from robot_tools.controllers import CartesianPoseController
|
from robot_tools.controllers import CartesianPoseController
|
||||||
from robot_tools.ros.conversions import *
|
from robot_tools.ros.conversions import *
|
||||||
from robot_tools.ros.tf import TransformTree
|
from robot_tools.ros.tf import TF2Client
|
||||||
from simulation import Simulation
|
from simulation import Simulation
|
||||||
|
|
||||||
|
|
||||||
class BtSimNode:
|
class BtSimNode:
|
||||||
def __init__(self, gui):
|
def __init__(self, gui):
|
||||||
self.sim = Simulation(gui=gui, sleep=False)
|
self.sim = Simulation(gui=gui, sleep=False)
|
||||||
self.controller = CartesianPoseController(self.sim.arm)
|
|
||||||
|
|
||||||
self.controller_update_rate = 60
|
self.controller_update_rate = 60
|
||||||
self.joint_state_publish_rate = 60
|
self.joint_state_publish_rate = 60
|
||||||
self.camera_publish_rate = 5
|
self.camera_publish_rate = 5
|
||||||
|
|
||||||
self.cv_bridge = cv_bridge.CvBridge()
|
self.cv_bridge = cv_bridge.CvBridge()
|
||||||
self.tf_tree = TransformTree()
|
self.tf_tree = TF2Client()
|
||||||
|
|
||||||
self.setup_robot_topics()
|
self.setup_robot_topics()
|
||||||
self.setup_camera_topics()
|
self.setup_camera_topics()
|
||||||
self.setup_gripper_actions()
|
self.setup_controllers()
|
||||||
|
self.setup_gripper_interface()
|
||||||
self.broadcast_transforms()
|
self.broadcast_transforms()
|
||||||
|
|
||||||
rospy.Service("reset", std_srvs.srv.Trigger, self.reset)
|
rospy.Service("reset", std_srvs.srv.Trigger, self.reset)
|
||||||
@ -40,10 +42,18 @@ class BtSimNode:
|
|||||||
|
|
||||||
def setup_robot_topics(self):
|
def setup_robot_topics(self):
|
||||||
self.joint_pub = rospy.Publisher("joint_states", JointState, queue_size=10)
|
self.joint_pub = rospy.Publisher("joint_states", JointState, queue_size=10)
|
||||||
rospy.Subscriber("cmd", Pose, self.target_pose_cb)
|
|
||||||
|
def setup_controllers(self):
|
||||||
|
self.cartesian_pose_controller = CartesianPoseController(
|
||||||
|
self.sim.arm, stopped=False
|
||||||
|
)
|
||||||
|
rospy.Subscriber("command", Pose, self.target_pose_cb)
|
||||||
|
|
||||||
def target_pose_cb(self, msg):
|
def target_pose_cb(self, msg):
|
||||||
self.controller.set_target(from_pose_msg(msg))
|
self.cartesian_pose_controller.set_target(from_pose_msg(msg))
|
||||||
|
|
||||||
|
def setup_gripper_interface(self):
|
||||||
|
self.gripper_interface = GripperInterface(self.sim.gripper)
|
||||||
|
|
||||||
def setup_camera_topics(self):
|
def setup_camera_topics(self):
|
||||||
self.cam_info_msg = to_camera_info_msg(self.sim.camera.intrinsic)
|
self.cam_info_msg = to_camera_info_msg(self.sim.camera.intrinsic)
|
||||||
@ -55,19 +65,6 @@ class BtSimNode:
|
|||||||
)
|
)
|
||||||
self.depth_pub = rospy.Publisher("/cam/depth/image_raw", Image, queue_size=10)
|
self.depth_pub = rospy.Publisher("/cam/depth/image_raw", Image, queue_size=10)
|
||||||
|
|
||||||
def setup_gripper_actions(self):
|
|
||||||
self.move_server = actionlib.SimpleActionServer(
|
|
||||||
"/franka_gripper/move",
|
|
||||||
franka_gripper.msg.MoveAction,
|
|
||||||
self.move,
|
|
||||||
False,
|
|
||||||
)
|
|
||||||
self.move_server.start()
|
|
||||||
|
|
||||||
def move(self, goal):
|
|
||||||
self.sim.gripper.move(goal.width)
|
|
||||||
self.move_server.set_succeeded()
|
|
||||||
|
|
||||||
def broadcast_transforms(self):
|
def broadcast_transforms(self):
|
||||||
msgs = []
|
msgs = []
|
||||||
msg = geometry_msgs.msg.TransformStamped()
|
msg = geometry_msgs.msg.TransformStamped()
|
||||||
@ -91,7 +88,7 @@ class BtSimNode:
|
|||||||
self.reset_requested = True
|
self.reset_requested = True
|
||||||
rospy.sleep(1.0) # wait for the latest sim step to finish
|
rospy.sleep(1.0) # wait for the latest sim step to finish
|
||||||
self.sim.reset()
|
self.sim.reset()
|
||||||
self.controller.set_target(self.sim.arm.pose())
|
self.cartesian_pose_controller.set_target(self.sim.arm.pose())
|
||||||
self.step_cnt = 0
|
self.step_cnt = 0
|
||||||
self.reset_requested = False
|
self.reset_requested = False
|
||||||
return std_srvs.srv.TriggerResponse(success=True)
|
return std_srvs.srv.TriggerResponse(success=True)
|
||||||
@ -107,7 +104,8 @@ class BtSimNode:
|
|||||||
|
|
||||||
def handle_updates(self):
|
def handle_updates(self):
|
||||||
if self.step_cnt % int(self.sim.rate / self.controller_update_rate) == 0:
|
if self.step_cnt % int(self.sim.rate / self.controller_update_rate) == 0:
|
||||||
self.controller.update()
|
self.cartesian_pose_controller.update()
|
||||||
|
self.gripper_interface.update(1.0 / 60.0)
|
||||||
if self.step_cnt % int(self.sim.rate / self.joint_state_publish_rate) == 0:
|
if self.step_cnt % int(self.sim.rate / self.joint_state_publish_rate) == 0:
|
||||||
self.publish_joint_state()
|
self.publish_joint_state()
|
||||||
if self.step_cnt % int(self.sim.rate / self.camera_publish_rate) == 0:
|
if self.step_cnt % int(self.sim.rate / self.camera_publish_rate) == 0:
|
||||||
@ -138,14 +136,86 @@ class BtSimNode:
|
|||||||
self.depth_pub.publish(depth_msg)
|
self.depth_pub.publish(depth_msg)
|
||||||
|
|
||||||
|
|
||||||
def main(args):
|
class GripperInterface:
|
||||||
|
def __init__(self, gripper):
|
||||||
|
self.gripper = gripper
|
||||||
|
self.move_server = actionlib.SimpleActionServer(
|
||||||
|
"/franka_gripper/move",
|
||||||
|
franka_gripper.msg.MoveAction,
|
||||||
|
auto_start=False,
|
||||||
|
)
|
||||||
|
self.move_server.register_goal_callback(self.goal_cb)
|
||||||
|
self.move_server.start()
|
||||||
|
|
||||||
|
def goal_cb(self):
|
||||||
|
goal = self.move_server.accept_new_goal()
|
||||||
|
self.gripper.move(goal.width)
|
||||||
|
self.elapsed_time = 0.0
|
||||||
|
|
||||||
|
def update(self, dt):
|
||||||
|
if self.move_server.is_active():
|
||||||
|
self.elapsed_time += dt
|
||||||
|
if self.elapsed_time > 1.0:
|
||||||
|
self.move_server.set_succeeded()
|
||||||
|
|
||||||
|
|
||||||
|
class JointTrajectoryController:
|
||||||
|
def __init__(self, arm, stopped=False):
|
||||||
|
self.arm = arm
|
||||||
|
self.action_server = actionlib.SimpleActionServer(
|
||||||
|
"position_joint_trajectory_controller/follow_joint_trajectory",
|
||||||
|
control_msgs.msg.FollowJointTrajectoryAction,
|
||||||
|
auto_start=False,
|
||||||
|
)
|
||||||
|
self.action_server.register_goal_callback(self.goal_cb)
|
||||||
|
self.action_server.start()
|
||||||
|
|
||||||
|
self.is_running = False
|
||||||
|
if not stopped:
|
||||||
|
self.start()
|
||||||
|
|
||||||
|
def goal_cb(self):
|
||||||
|
goal = self.action_server.accept_new_goal()
|
||||||
|
self.elapsed_time = 0.0
|
||||||
|
self.points = iter(goal.trajectory.points)
|
||||||
|
self.next_point = next(self.points)
|
||||||
|
|
||||||
|
def start(self):
|
||||||
|
self.is_running = True
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
self.is_running = False
|
||||||
|
|
||||||
|
def update(self, dt):
|
||||||
|
if not (self.is_running and self.action_server.is_active()):
|
||||||
|
return
|
||||||
|
|
||||||
|
self.elapsed_time += dt
|
||||||
|
if self.elapsed_time > self.next_point.time_from_start.to_sec():
|
||||||
|
try:
|
||||||
|
self.next_point = next(self.points)
|
||||||
|
except StopIteration:
|
||||||
|
self.action_server.set_succeeded()
|
||||||
|
return
|
||||||
|
|
||||||
|
self.arm.set_desired_joint_positions(self.next_point.positions)
|
||||||
|
|
||||||
|
|
||||||
|
def create_parser():
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument("--gui", action="store_true")
|
||||||
|
return parser
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
rospy.init_node("bt_sim")
|
rospy.init_node("bt_sim")
|
||||||
|
|
||||||
|
parser = create_parser()
|
||||||
|
args, _ = parser.parse_known_args()
|
||||||
|
|
||||||
server = BtSimNode(args.gui)
|
server = BtSimNode(args.gui)
|
||||||
server.run()
|
server.run()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
parser = argparse.ArgumentParser()
|
main()
|
||||||
parser.add_argument("--gui", action="store_true")
|
|
||||||
args, _ = parser.parse_known_args()
|
|
||||||
main(args)
|
|
||||||
|
@ -11,6 +11,9 @@
|
|||||||
<node pkg="active_grasp" type="bt_sim_node.py" name="simulation" args="--gui" output="screen" />
|
<node pkg="active_grasp" type="bt_sim_node.py" name="simulation" args="--gui" output="screen" />
|
||||||
<node pkg="robot_state_publisher" type="robot_state_publisher" name="robot_state_publisher" />
|
<node pkg="robot_state_publisher" type="robot_state_publisher" name="robot_state_publisher" />
|
||||||
|
|
||||||
|
<!-- Launch MoveIt -->
|
||||||
|
<!-- <include file="$(find panda_moveit_config)/launch/move_group.launch" /> -->
|
||||||
|
|
||||||
<!-- Visualize the robot. -->
|
<!-- Visualize the robot. -->
|
||||||
<node pkg="rviz" type="rviz" name="rviz" args="-d $(find active_grasp)/launch/panda_visualization.rviz" if="$(arg launch_rviz)" />
|
<node pkg="rviz" type="rviz" name="rviz" args="-d $(find active_grasp)/launch/panda_visualization.rviz" if="$(arg launch_rviz)" />
|
||||||
</launch>
|
</launch>
|
||||||
|
43
policies.py
43
policies.py
@ -10,8 +10,9 @@ import std_srvs.srv
|
|||||||
|
|
||||||
from robot_tools.spatial import Rotation, Transform
|
from robot_tools.spatial import Rotation, Transform
|
||||||
from robot_tools.ros.conversions import *
|
from robot_tools.ros.conversions import *
|
||||||
|
from robot_tools.ros.control import ControllerManagerClient
|
||||||
from robot_tools.ros.panda import PandaGripperClient
|
from robot_tools.ros.panda import PandaGripperClient
|
||||||
from robot_tools.ros.tf import TransformTree
|
from robot_tools.ros.tf import TF2Client
|
||||||
from robot_tools.perception import *
|
from robot_tools.perception import *
|
||||||
from vgn import vis
|
from vgn import vis
|
||||||
from vgn.detection import VGN, compute_grasps
|
from vgn.detection import VGN, compute_grasps
|
||||||
@ -34,7 +35,7 @@ class BaseController:
|
|||||||
self.length = rospy.get_param("~length")
|
self.length = rospy.get_param("~length")
|
||||||
|
|
||||||
self.cv_bridge = cv_bridge.CvBridge()
|
self.cv_bridge = cv_bridge.CvBridge()
|
||||||
self.tf = TransformTree()
|
self.tf = TF2Client()
|
||||||
|
|
||||||
self.reset_client = rospy.ServiceProxy("/reset", std_srvs.srv.Trigger)
|
self.reset_client = rospy.ServiceProxy("/reset", std_srvs.srv.Trigger)
|
||||||
|
|
||||||
@ -49,9 +50,12 @@ class BaseController:
|
|||||||
self.base_frame_id = rospy.get_param("~base_frame_id")
|
self.base_frame_id = rospy.get_param("~base_frame_id")
|
||||||
self.ee_frame_id = rospy.get_param("~ee_frame_id")
|
self.ee_frame_id = rospy.get_param("~ee_frame_id")
|
||||||
self.ee_grasp_offset = Transform.from_list(rospy.get_param("~ee_grasp_offset"))
|
self.ee_grasp_offset = Transform.from_list(rospy.get_param("~ee_grasp_offset"))
|
||||||
self.target_pose_pub = rospy.Publisher("/cmd", Pose, queue_size=10)
|
self.target_pose_pub = rospy.Publisher("/command", Pose, queue_size=10)
|
||||||
self.gripper = PandaGripperClient()
|
self.gripper = PandaGripperClient()
|
||||||
|
|
||||||
|
def send_pose_command(self, target):
|
||||||
|
self.target_pose_pub.publish(to_pose_msg(target))
|
||||||
|
|
||||||
def setup_camera_connection(self):
|
def setup_camera_connection(self):
|
||||||
self.cam_frame_id = rospy.get_param("~camera/frame_id")
|
self.cam_frame_id = rospy.get_param("~camera/frame_id")
|
||||||
info_topic = rospy.get_param("~camera/info_topic")
|
info_topic = rospy.get_param("~camera/info_topic")
|
||||||
@ -78,6 +82,7 @@ class BaseController:
|
|||||||
self.execute_grasp()
|
self.execute_grasp()
|
||||||
|
|
||||||
def reset(self):
|
def reset(self):
|
||||||
|
vis.clear()
|
||||||
req = std_srvs.srv.TriggerRequest()
|
req = std_srvs.srv.TriggerRequest()
|
||||||
self.reset_client(req)
|
self.reset_client(req)
|
||||||
rospy.sleep(1.0) # wait for states to be updated
|
rospy.sleep(1.0) # wait for states to be updated
|
||||||
@ -104,13 +109,11 @@ class BaseController:
|
|||||||
target = self.T_B_O * grasp.pose * self.ee_grasp_offset.inv()
|
target = self.T_B_O * grasp.pose * self.ee_grasp_offset.inv()
|
||||||
|
|
||||||
self.gripper.move(0.08)
|
self.gripper.move(0.08)
|
||||||
rospy.sleep(1.0) # TODO properly implement the simulated move server
|
self.send_pose_command(target)
|
||||||
self.target_pose_pub.publish(to_pose_msg(target))
|
rospy.sleep(3.0)
|
||||||
rospy.sleep(2.0)
|
|
||||||
self.gripper.move(0.0)
|
self.gripper.move(0.0)
|
||||||
rospy.sleep(1.0) # TODO
|
|
||||||
target.translation[2] += 0.3
|
target.translation[2] += 0.3
|
||||||
self.target_pose_pub.publish(to_pose_msg(target))
|
self.send_pose_command(target)
|
||||||
rospy.sleep(2.0)
|
rospy.sleep(2.0)
|
||||||
|
|
||||||
def predict_best_grasp(self):
|
def predict_best_grasp(self):
|
||||||
@ -176,8 +179,30 @@ class FixedTrajectoryBaseline(BaseController):
|
|||||||
self.center
|
self.center
|
||||||
+ np.r_[self.radius * np.cos(t), self.radius * np.sin(t), 0.0]
|
+ np.r_[self.radius * np.cos(t), self.radius * np.sin(t), 0.0]
|
||||||
)
|
)
|
||||||
self.target_pose_pub.publish(to_pose_msg(self.target))
|
self.send_pose_command(self.target)
|
||||||
|
|
||||||
|
|
||||||
|
class Map:
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def update(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class MultiViewPicking(BaseController):
|
class MultiViewPicking(BaseController):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__()
|
||||||
|
self.rate = 5
|
||||||
|
self.grid = np.zeros((40, 40, 40))
|
||||||
|
|
||||||
|
def reset(self):
|
||||||
|
super().reset()
|
||||||
|
self.tic = rospy.Time.now()
|
||||||
|
timeout = rospy.Duration(0.1)
|
||||||
|
x0 = self.tf.lookup(self.base_frame_id, self.ee_frame_id, self.tic, timeout)
|
||||||
|
self.center = np.r_[x0.translation[0] + self.radius, x0.translation[1:]]
|
||||||
|
self.target = x0
|
||||||
|
|
||||||
|
def update(self):
|
||||||
pass
|
pass
|
||||||
|
@ -27,7 +27,7 @@ class Simulation(BtManipulationSim):
|
|||||||
ori = Rotation.from_rotvec(np.array([0, 0, np.pi / 2])).as_quat()
|
ori = Rotation.from_rotvec(np.array([0, 0, np.pi / 2])).as_quat()
|
||||||
p.loadURDF("table/table.urdf", baseOrientation=ori, useFixedBase=True)
|
p.loadURDF("table/table.urdf", baseOrientation=ori, useFixedBase=True)
|
||||||
self.length = 0.3
|
self.length = 0.3
|
||||||
self.origin = [-0.2, -0.5 * self.length, 0.5]
|
self.origin = [-0.3, -0.5 * self.length, 0.5]
|
||||||
|
|
||||||
def add_robot(self):
|
def add_robot(self):
|
||||||
self.T_W_B = Transform(Rotation.identity(), np.r_[-0.6, 0.0, 0.5])
|
self.T_W_B = Transform(Rotation.identity(), np.r_[-0.6, 0.0, 0.5])
|
||||||
@ -39,7 +39,8 @@ class Simulation(BtManipulationSim):
|
|||||||
self.remove_all_objects()
|
self.remove_all_objects()
|
||||||
self.set_initial_arm_configuration()
|
self.set_initial_arm_configuration()
|
||||||
urdfs = np.random.choice(self.urdfs, 4)
|
urdfs = np.random.choice(self.urdfs, 4)
|
||||||
self.add_random_arrangement(urdfs, np.r_[self.origin[:2], 0.625], self.length)
|
origin = np.r_[self.origin[:2], 0.625]
|
||||||
|
self.add_random_arrangement(urdfs, origin, self.length, 0.8)
|
||||||
|
|
||||||
def set_initial_arm_configuration(self):
|
def set_initial_arm_configuration(self):
|
||||||
q = self.arm.configurations["ready"]
|
q = self.arm.configurations["ready"]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user