diff --git a/CMakeLists.txt b/CMakeLists.txt index 5c50555..5eabbdc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,6 +34,7 @@ endforeach() install(PROGRAMS scripts/move_mss + scripts/move_sun.py DESTINATION lib/${PROJECT_NAME} ) @@ -42,7 +43,7 @@ install(PROGRAMS #) install( - DIRECTORY + DIRECTORY launch rviz meshes robots urdf config worlds DESTINATION share/${PROJECT_NAME} ) diff --git a/config/mobile_servicing_system_control.yaml b/config/mobile_servicing_system_control.yaml index 4bd725e..3d12c6a 100644 --- a/config/mobile_servicing_system_control.yaml +++ b/config/mobile_servicing_system_control.yaml @@ -29,6 +29,9 @@ starboard_bga_joint_trajectory_controller: type: joint_trajectory_controller/JointTrajectoryController + camera_joint_trajectory_controller: + type: joint_trajectory_controller/JointTrajectoryController + /dextre_body_joint_trajectory_controller: ros__parameters: @@ -197,8 +200,36 @@ stopped_velocity_tolerance: 0.1 goal_time: 0.0 -/gz_ros_control: +/camera_joint_trajectory_controller: ros__parameters: - # P-gain across all joints in gazebo's position interface - # https://control.ros.org/humble/doc/gz_ros2_control/doc/index.html#notes-on-the-command-interface - position_proportional_gain: 0.05 + allow_nonzero_velocity_at_trajectory_end: false + joints: + - boom_a_clpa_pan_joint + - boom_a_clpa_tilt_joint + - boom_b_clpa_pan_joint + - boom_b_clpa_tilt_joint + - outrigger_1_clpa_pan_joint + - outrigger_1_clpa_tilt_joint + - outrigger_2_clpa_pan_joint + - outrigger_2_clpa_tilt_joint + - etvcg_cp3_pan_joint + - etvcg_cp3_tilt_joint + - etvcg_cp8_pan_joint + - etvcg_cp8_tilt_joint + - etvcg_cp9_pan_joint + - etvcg_cp9_tilt_joint + - etvcg_cp13_pan_joint + - etvcg_cp13_tilt_joint + interface_name: position + command_interfaces: + - position + state_interfaces: + - position + - velocity + state_publish_rate: 100.0 + action_monitor_rate: 20.0 + allow_partial_joints_goal: true + constraints: + stopped_velocity_tolerance: 0.1 + goal_time: 0.0 + diff --git a/launch/spawn_mobile_servicing_system.launch.py b/launch/spawn_mobile_servicing_system.launch.py index 02cc27a..b282e39 100644 --- a/launch/spawn_mobile_servicing_system.launch.py +++ b/launch/spawn_mobile_servicing_system.launch.py @@ -14,9 +14,12 @@ def generate_launch_description(): launch_args = [ - DeclareLaunchArgument(name="move_demo", default_value="True"), + DeclareLaunchArgument(name="move_demo", default_value="False"), ] + # Common parameters for all nodes + sim_time_params = [{"use_sim_time": True}] + # URDF mss_urdf = os.path.join(get_package_share_directory("iss_description"), "robots", "mobile_servicing_system.urdf.xacro") mss_doc = xacro.process_file(mss_urdf) @@ -53,6 +56,7 @@ def generate_launch_description(): package="iss_description", executable="move_mss", output="screen", + parameters=sim_time_params, # Ensure this uses sim time too condition=IfCondition(LaunchConfiguration('move_demo')) ) @@ -63,6 +67,7 @@ def generate_launch_description(): arguments=["joint_state_broadcaster", "--controller-manager", "/controller_manager", "--switch-timeout", "100.0"], name="start_joint_state_broadcaster", output="screen", + parameters=sim_time_params, # ) canadarm2_joint_controller_spawner = Node( @@ -71,6 +76,7 @@ def generate_launch_description(): arguments=["canadarm2_joint_trajectory_controller", "-c", "/controller_manager", "--switch-timeout", "100.0"], name="start_canadarm2_joint_trajectory_controller", output="screen", + parameters=sim_time_params, ) dextre_arm_1_joint_controller_spawner = Node( @@ -79,6 +85,7 @@ def generate_launch_description(): arguments=["dextre_arm_1_joint_trajectory_controller", "-c", "/controller_manager", "--switch-timeout", "100.0"], name="start_dextre_arm_1_joint_trajectory_controller", output="screen", + parameters=sim_time_params, ) dextre_arm_2_joint_controller_spawner = Node( @@ -87,6 +94,7 @@ def generate_launch_description(): arguments=["dextre_arm_2_joint_trajectory_controller", "-c", "/controller_manager", "--switch-timeout", "100.0"], name="start_dextre_arm_2_joint_trajectory_controller", output="screen", + parameters=sim_time_params, ) mobile_base_system_joint_controller_spawner = Node( @@ -95,6 +103,7 @@ def generate_launch_description(): arguments=["mobile_base_system_joint_trajectory_controller", "-c", "/controller_manager", "--switch-timeout", "100.0"], name="start_mobile_base_system_joint_trajectory_controller", output="screen", + parameters=sim_time_params, ) dextre_body_joint_controller_spawner = Node( @@ -103,6 +112,7 @@ def generate_launch_description(): arguments=["dextre_body_joint_trajectory_controller", "-c", "/controller_manager", "--switch-timeout", "100.0"], name="start_dextre_body_joint_trajectory_controller", output="screen", + parameters=sim_time_params, ) sarj_joint_controller_spawner = Node( @@ -111,6 +121,7 @@ def generate_launch_description(): arguments=["sarj_joint_trajectory_controller", "-c", "/controller_manager", "--switch-timeout", "100.0"], name="start_sarj_joint_trajectory_controller", output="screen", + parameters=sim_time_params, ) port_bga_joint_controller_spawner = Node( @@ -119,6 +130,7 @@ def generate_launch_description(): arguments=["port_bga_joint_trajectory_controller", "-c", "/controller_manager", "--switch-timeout", "100.0"], name="start_port_bga_joint_trajectory_controller", output="screen", + parameters=sim_time_params, ) starboard_bga_joint_controller_spawner = Node( @@ -127,21 +139,64 @@ def generate_launch_description(): arguments=["starboard_bga_joint_trajectory_controller", "-c", "/controller_manager", "--switch-timeout", "100.0"], name="start_starboard_bga_joint_trajectory_controller", output="screen", + parameters=sim_time_params, ) - - image_bridge = Node( - package="ros_gz_image", - executable="image_bridge", - arguments=["/image_raw", "/image_raw"], - output="screen" + camera_joint_controller_spawner = Node( + package="controller_manager", + executable="spawner", + arguments=["camera_joint_trajectory_controller", "-c", "/controller_manager", "--switch-timeout", "100.0"], + name="start_camera_joint_trajectory_controller", + output="screen", + parameters=sim_time_params, ) + # Bridge nodes for pan-tilt cameras + camera_names = [ + "boom_a_clpa", + "boom_b_clpa", + "outrigger_1_clpa", + "outrigger_2_clpa", + "etvcg_cp3", + "etvcg_cp8", + "etvcg_cp9", + "etvcg_cp13" + ] + + camera_bridges = [] + for camera_name in camera_names: + camera_bridges.append( + Node( + package="ros_gz_image", + executable="image_bridge", + name=f"{camera_name}_image_bridge", + arguments=[f"/{camera_name}/image_raw"], + output="screen", + parameters=[{ + "use_sim_time": True, + }], + ) + ) + # Bridge camera_info topic, frame is wrong but handled by static tf + camera_bridges.append( + Node( + package="ros_gz_bridge", + executable="parameter_bridge", + arguments=[f"/{camera_name}/camera_info@sensor_msgs/msg/CameraInfo[gz.msgs.CameraInfo"], + output="screen", + name=f"{camera_name}_info_bridge", + parameters=[{ + 'use_sim_time': True, + }] + ) + ) + + return LaunchDescription( launch_args + [ mss_robot_state_publisher, mss_spawn, mss_move, - image_bridge, + ] + camera_bridges + [ RegisterEventHandler( OnProcessExit( target_action=mss_spawn, @@ -151,14 +206,15 @@ def generate_launch_description(): RegisterEventHandler( OnProcessExit( target_action=joint_state_broadcaster_spawner, - on_exit=[canadarm2_joint_controller_spawner, + on_exit=[canadarm2_joint_controller_spawner, dextre_arm_1_joint_controller_spawner, dextre_arm_2_joint_controller_spawner, mobile_base_system_joint_controller_spawner, dextre_body_joint_controller_spawner, sarj_joint_controller_spawner, starboard_bga_joint_controller_spawner, - port_bga_joint_controller_spawner], + port_bga_joint_controller_spawner, + camera_joint_controller_spawner], ) ) - ]) + ]) \ No newline at end of file diff --git a/robots/mobile_servicing_system.urdf.xacro b/robots/mobile_servicing_system.urdf.xacro index 91e4386..5948e43 100644 --- a/robots/mobile_servicing_system.urdf.xacro +++ b/robots/mobile_servicing_system.urdf.xacro @@ -5,7 +5,8 @@ - + + @@ -13,12 +14,15 @@ - + - + - + + + + diff --git a/rviz/iss.rviz b/rviz/iss.rviz index 71de629..fc78877 100644 --- a/rviz/iss.rviz +++ b/rviz/iss.rviz @@ -6,8 +6,10 @@ Panels: Expanded: - /Global Options1 - /Status1 + - /Camera1 + - /CameraInfo1 Splitter Ratio: 0.5 - Tree Height: 746 + Tree Height: 752 - Class: rviz_common/Selection Name: Selection - Class: rviz_common/Tool Properties @@ -65,7 +67,48 @@ Visualization Manager: Expand Link Details: false Expand Tree: false Link Tree Style: Links in Alphabetic Order - body: + boom_a_clpa_base_link: + Alpha: 1 + Show Axes: false + Show Trail: false + boom_a_clpa_camera_link: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + boom_a_clpa_optical_frame: + Alpha: 1 + Show Axes: false + Show Trail: false + boom_a_clpa_pan_link: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + boom_a_clpa_tilt_link: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + boom_b_clpa_base_link: + Alpha: 1 + Show Axes: false + Show Trail: false + boom_b_clpa_camera_link: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + boom_b_clpa_optical_frame: + Alpha: 1 + Show Axes: false + Show Trail: false + boom_b_clpa_pan_link: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + boom_b_clpa_tilt_link: Alpha: 1 Show Axes: false Show Trail: false @@ -190,10 +233,116 @@ Visualization Manager: Show Axes: false Show Trail: false Value: true + etvcg_cp13_base_link: + Alpha: 1 + Show Axes: false + Show Trail: false + etvcg_cp13_camera_link: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + etvcg_cp13_optical_frame: + Alpha: 1 + Show Axes: false + Show Trail: false + etvcg_cp13_pan_link: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + etvcg_cp13_tilt_link: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + etvcg_cp3_base_link: + Alpha: 1 + Show Axes: false + Show Trail: false + etvcg_cp3_camera_link: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + etvcg_cp3_optical_frame: + Alpha: 1 + Show Axes: false + Show Trail: false + etvcg_cp3_pan_link: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + etvcg_cp3_tilt_link: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + etvcg_cp8_base_link: + Alpha: 1 + Show Axes: false + Show Trail: false + etvcg_cp8_camera_link: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + etvcg_cp8_optical_frame: + Alpha: 1 + Show Axes: false + Show Trail: false + etvcg_cp8_pan_link: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + etvcg_cp8_tilt_link: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + etvcg_cp9_base_link: + Alpha: 1 + Show Axes: false + Show Trail: false + etvcg_cp9_camera_link: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + etvcg_cp9_optical_frame: + Alpha: 1 + Show Axes: false + Show Trail: false + etvcg_cp9_pan_link: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + etvcg_cp9_tilt_link: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true link_02_unity_node: Alpha: 1 Show Axes: false Show Trail: false + link_08_p6_truss: + Alpha: 1 + Show Axes: false + Show Trail: false + link_08_p6_truss_01: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + link_08_p6_truss_02: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true link_09_destiny: Alpha: 1 Show Axes: false @@ -202,11 +351,125 @@ Visualization Manager: Alpha: 1 Show Axes: false Show Trail: false + link_16_s1_truss: + Alpha: 1 + Show Axes: false + Show Trail: false + link_17_p1_truss: + Alpha: 1 + Show Axes: false + Show Trail: false + link_19_p3_truss: + Alpha: 1 + Show Axes: false + Show Trail: false + link_20_p4_truss: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + link_20_p4_truss_01: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + link_20_p4_truss_02: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + link_21_p5_truss: + Alpha: 1 + Show Axes: false + Show Trail: false + link_22_s3_truss: + Alpha: 1 + Show Axes: false + Show Trail: false + link_23_s4_truss: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + link_23_s4_truss_01: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + link_23_s4_truss_02: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + link_24_s5_truss: + Alpha: 1 + Show Axes: false + Show Trail: false + link_32_s6_truss: + Alpha: 1 + Show Axes: false + Show Trail: false + link_32_s6_truss_01: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + link_32_s6_truss_02: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true mobile_base_system: Alpha: 1 Show Axes: false Show Trail: false Value: true + outrigger_1_clpa_base_link: + Alpha: 1 + Show Axes: false + Show Trail: false + outrigger_1_clpa_camera_link: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + outrigger_1_clpa_optical_frame: + Alpha: 1 + Show Axes: false + Show Trail: false + outrigger_1_clpa_pan_link: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + outrigger_1_clpa_tilt_link: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + outrigger_2_clpa_base_link: + Alpha: 1 + Show Axes: false + Show Trail: false + outrigger_2_clpa_camera_link: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + outrigger_2_clpa_optical_frame: + Alpha: 1 + Show Axes: false + Show Trail: false + outrigger_2_clpa_pan_link: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + outrigger_2_clpa_tilt_link: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true pdgf: Alpha: 1 Show Axes: false @@ -215,6 +478,15 @@ Visualization Manager: Alpha: 1 Show Axes: false Show Trail: false + root: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + world: + Alpha: 1 + Show Axes: false + Show Trail: false Mass Properties: Inertia: false Mass: false @@ -237,6 +509,44 @@ Visualization Manager: Radius: 0.05000000074505806 Reference Frame: dextre_arm_2_shoulder_roll Value: true + - Class: rviz_default_plugins/Camera + Enabled: false + Far Plane Distance: 100 + Image Rendering: background and overlay + Name: Camera + Overlay Alpha: 0.5 + Topic: + Depth: 5 + Durability Policy: Volatile + History Policy: Keep Last + Reliability Policy: Reliable + Value: /boom_a_clpa/image_raw + Value: false + Visibility: + Axes: true + CameraInfo: true + Grid: true + RobotModel: true + Value: true + Zoom Factor: 1 + - Alpha: 0.5 + Class: rviz_default_plugins/CameraInfo + Color: 85; 255; 255 + Edge color: 85; 255; 255 + Enabled: true + Far clip: 1 + Name: CameraInfo + Not show side polygons: true + Show edges: true + Show polygons: true + Topic: + Depth: 5 + Durability Policy: Volatile + Filter size: 10 + History Policy: Keep Last + Reliability Policy: Reliable + Value: /boom_a_clpa/camera_info + Value: true Enabled: true Global Options: Background Color: 0; 0; 0 @@ -283,33 +593,35 @@ Visualization Manager: Views: Current: Class: rviz_default_plugins/Orbit - Distance: 97.93163299560547 + Distance: 7.807682037353516 Enable Stereo Rendering: Stereo Eye Separation: 0.05999999865889549 Stereo Focal Distance: 1 Swap Stereo Eyes: false Value: false Focal Point: - X: -6.481820583343506 - Y: -4.4895853996276855 - Z: 11.229458808898926 + X: -8.9642915725708 + Y: -9.175496101379395 + Z: 7.597785949707031 Focal Shape Fixed Size: true Focal Shape Size: 0.05000000074505806 Invert Z Axis: false Name: Current View Near Clip Distance: 0.009999999776482582 - Pitch: 0.5647977590560913 + Pitch: 0.22479797899723053 Target Frame: Value: Orbit (rviz) - Yaw: 4.506348133087158 + Yaw: 3.3663418292999268 Saved: ~ Window Geometry: - Displays: + Camera: collapsed: false + Displays: + collapsed: true Height: 1043 - Hide Left Dock: false + Hide Left Dock: true Hide Right Dock: true - QMainWindow State: 000000ff00000000fd00000004000000000000015600000375fc0200000008fb0000001200530065006c0065006300740069006f006e00000001e10000009b0000005c00fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed000001df00000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c006100790073010000003d00000375000000c900fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261000000010000010f00000375fc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a00560069006500770073000000003d00000375000000a400fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e100000197000000030000073e0000003efc0100000002fb0000000800540069006d006501000000000000073e0000026f00fffffffb0000000800540069006d00650100000000000004500000000000000000000005e20000037500000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000 + QMainWindow State: 000000ff00000000fd00000004000000000000015600000379fc0200000009fb0000001200530065006c0065006300740069006f006e00000001e10000009b0000005c00fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed000001df00000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c006100790073000000003b00000379000000c700fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261fb0000000c00430061006d006500720061020000008500000118000002a90000021b000000010000010f00000375fc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a00560069006500770073000000003d00000375000000a000fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e100000197000000030000073e0000003efc0100000002fb0000000800540069006d006501000000000000073e0000025300fffffffb0000000800540069006d006501000000000000045000000000000000000000073e0000037900000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000 Selection: collapsed: false Time: @@ -320,4 +632,4 @@ Window Geometry: collapsed: true Width: 1854 X: 66 - Y: 0 + Y: 32 diff --git a/scripts/move_mss b/scripts/move_mss index 02d88cc..926d7cc 100755 --- a/scripts/move_mss +++ b/scripts/move_mss @@ -1,111 +1,101 @@ #!/usr/bin/env python3 +import sys import rclpy +from rclpy.action import ActionClient from rclpy.node import Node from builtin_interfaces.msg import Duration - -from std_msgs.msg import String, Float64 from trajectory_msgs.msg import JointTrajectory, JointTrajectoryPoint -from std_srvs.srv import Empty - -class MoveArm(Node): - - def __init__(self): - super().__init__('arm_node') - self.canadarm2_publisher_ = self.create_publisher(JointTrajectory, '/canadarm2_joint_trajectory_controller/joint_trajectory', 10) - self.mbs_publisher_ = self.create_publisher(JointTrajectory, '/mobile_base_system_joint_trajectory_controller/joint_trajectory', 10) - - self.canadarm2_pose_0_srv = self.create_service(Empty, 'canadarm2_pose_0', self.canadarm2_pose_0_callback) - self.canadarm2_pose_1_srv = self.create_service(Empty, 'canadarm2_pose_1', self.canadarm2_pose_1_callback) - - self.mbs_pose_0_srv = self.create_service(Empty, 'mbs_pose_0', self.mbs_pose_0_callback) - self.mbs_pose_1_srv = self.create_service(Empty, 'mbs_pose_1', self.mbs_pose_1_callback) - self.mbs_pose_2_srv = self.create_service(Empty, 'mbs_pose_2', self.mbs_pose_1_callback) - - self.canadarm2_joints = ["joint_canadarm2_1", "joint_canadarm2_2", "joint_canadarm2_3", "joint_canadarm2_4", "joint_canadarm2_5", "joint_canadarm2_6", "joint_canadarm2_7"] - - self.mbs_joints = ["joint_mbs"] - - def canadarm2_pose_0_callback(self, request, response): - traj = JointTrajectory() - traj.joint_names = self.canadarm2_joints - - point1 = JointTrajectoryPoint() - point1.positions = [0.0, 0.628, -0.187, 0.0, 0.0, 0.0, 0.0] - point1.time_from_start = Duration(sec=30) - - traj.points.append(point1) - self.canadarm2_publisher_.publish(traj) - - return response - - def canadarm2_pose_1_callback(self, request, response): - traj = JointTrajectory() - traj.joint_names = self.canadarm2_joints - - point1 = JointTrajectoryPoint() - point1.positions = [0.51, 1.48, -0.677, 0.534, -0.062, -0.645, -0.755] - point1.time_from_start = Duration(sec=30) - - traj.points.append(point1) - self.canadarm2_publisher_.publish(traj) - - return response - - def mbs_pose_0_callback(self, request, response): - traj = JointTrajectory() - traj.joint_names = self.mbs_joints - - point1 = JointTrajectoryPoint() - point1.positions = [0.0] - point1.time_from_start = Duration(sec=30) - - traj.points.append(point1) - self.mbs_publisher_.publish(traj) - - return response - - def mbs_pose_1_callback(self, request, response): - traj = JointTrajectory() - traj.joint_names = self.mbs_joints - - point1 = JointTrajectoryPoint() - point1.positions = [8.0] - point1.time_from_start = Duration(sec=30) - - traj.points.append(point1) - self.mbs_publisher_.publish(traj) - - return response - - def mbs_pose_2_callback(self, request, response): - traj = JointTrajectory() - traj.joint_names = self.mbs_joints - - point1 = JointTrajectoryPoint() - point1.positions = [-4.0] - point1.time_from_start = Duration(sec=30) - - traj.points.append(point1) - self.mbs_publisher_.publish(traj) - - return response - - - - -def main(args=None): - rclpy.init(args=args) - - arm_node = MoveArm() - - rclpy.spin(arm_node) - # Destroy the node explicitly - # (optional - otherwise it will be done automatically - # when the garbage collector destroys the node object) - arm_node.destroy_node() +from control_msgs.action import FollowJointTrajectory +from itertools import zip_longest + +# Helper function to send a goal and return the result future (non-blocking) +def start_trajectory(node, client, joint_names, positions): + if positions is None: + return None + + traj = JointTrajectory() + traj.joint_names = joint_names + point = JointTrajectoryPoint() + point.positions = positions + point.time_from_start = Duration(sec=30) + traj.points.append(point) + + goal_msg = FollowJointTrajectory.Goal() + goal_msg.trajectory = traj + + # Send goal + print(f"Sending goal to {client._action_name}...") + send_goal_future = client.send_goal_async(goal_msg) + + # Wait strictly for the server to ACCEPT the goal (fast) + rclpy.spin_until_future_complete(node, send_goal_future) + goal_handle = send_goal_future.result() + + if not goal_handle.accepted: + print(f"Goal rejected for {client._action_name}") + return None + + # Return the future that tracks the actual execution (slow) + return goal_handle.get_result_async() + +def main(): + rclpy.init() + node = rclpy.create_node('simple_arm_mover') + + # 1. Setup Data + canadarm2_joints = [ + "joint_canadarm2_1", "joint_canadarm2_2", "joint_canadarm2_3", + "joint_canadarm2_4", "joint_canadarm2_5", "joint_canadarm2_6", + "joint_canadarm2_7" + ] + mbs_joints = ["joint_mbs"] + + canadarm2_poses = [ + [0.51, 1.48, -0.677, 0.534, -0.062, -0.645, -0.755], + [0.0, 0.628, -0.187, 0.0, 0.0, 0.0, 0.0] + ] + mbs_poses = [ + [0.0], + [8.0], + [-4.0] + ] + + # 2. Setup Clients + arm_client = ActionClient( + node, FollowJointTrajectory, + '/canadarm2_joint_trajectory_controller/follow_joint_trajectory' + ) + mbs_client = ActionClient( + node, FollowJointTrajectory, + '/mobile_base_system_joint_trajectory_controller/follow_joint_trajectory' + ) + + print("Waiting for action servers...") + arm_client.wait_for_server() + mbs_client.wait_for_server() + print("Servers ready.") + + # 3. Iterate through poses (zipping ensures we handle different list lengths) + # zip_longest allows the shorter list to return 'None' while the longer continues + for i, (arm_pos, mbs_pos) in enumerate(zip_longest(canadarm2_poses, mbs_poses)): + + print(f"\n--- Starting Pose Set {i} ---") + + # Start both movements concurrently + future_arm = start_trajectory(node, arm_client, canadarm2_joints, arm_pos) + future_mbs = start_trajectory(node, mbs_client, mbs_joints, mbs_pos) + + # Wait until BOTH are done + while (future_arm and not future_arm.done()) or (future_mbs and not future_mbs.done()): + rclpy.spin_once(node, timeout_sec=0.1) + + print(f"Pose Set {i} complete.") + + # 4. Cleanup and Exit + print("\nAll poses finished. Exiting.") + node.destroy_node() rclpy.shutdown() - if __name__ == '__main__': - main() + main() \ No newline at end of file diff --git a/scripts/move_sun.py b/scripts/move_sun.py new file mode 100644 index 0000000..b956137 --- /dev/null +++ b/scripts/move_sun.py @@ -0,0 +1,63 @@ +#!/usr/bin/env python3 +import subprocess +import math +import argparse + +TARGET_NAME = "sun_model" +WORLD_NAME = "default" +ORBIT_RADIUS = 10000.0 + +def get_x_axis_rotation_quaternion(y, z): + """ + Calculates the 'Roll' (Rotation around X-axis) needed + for a light at (0, y, z) to point its -Z axis at (0,0,0). + """ + # 1. Calculate the angle from the vertical (Zenith) + # math.atan2(y, z) gives the angle of the vector relative to vertical. + # Since the light points Down (-Z), we negate the angle to rotate it correctly. + roll = -math.atan2(y, z) + + # 2. Convert Euler Roll to Quaternion + # Rotation around X-axis: q = [sin(theta/2), 0, 0, cos(theta/2)] + qx = math.sin(roll / 2.0) + qw = math.cos(roll / 2.0) + + # Y and Z components of the quaternion are 0 for pure X-axis rotation + return (qx, 0.0, 0.0, qw) + +def set_sun_pose(angle_degrees): + rad = math.radians(angle_degrees) + + # --- CHANGED: ORBIT IN Y-Z PLANE (Rotate around X) --- + x = 0 + y = ORBIT_RADIUS * math.sin(rad) + z = ORBIT_RADIUS * math.cos(rad) + + # Safety: don't go underground + if z < 100: z = 100 + + # Calculate Orientation (Roll instead of Pitch) + qx, qy, qz, qw = get_x_axis_rotation_quaternion(y, z) + + print(f"Moving {TARGET_NAME} (X-Axis Rot) -> Angle {angle_degrees}° | Pos [0, {y:.0f}, {z:.0f}]") + + req_str = ( + f'name: "{TARGET_NAME}", ' + f'position: {{x: {x:.1f}, y: {y:.1f}, z: {z:.1f}}}, ' + f'orientation: {{x: {qx:.4f}, y: {qy:.4f}, z: {qz:.4f}, w: {qw:.4f}}}' + ) + + cmd = [ + "gz", "service", + "-s", f"/world/{WORLD_NAME}/set_pose", + "--reqtype", "gz.msgs.Pose", + "--reptype", "gz.msgs.Boolean", + "--req", req_str + ] + subprocess.run(cmd) + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument("--angle", type=float, default=0.0) + args = parser.parse_args() + set_sun_pose(args.angle) \ No newline at end of file diff --git a/urdf/canadarm2.urdf.xacro b/urdf/canadarm2.urdf.xacro index d09cced..e58bf2f 100644 --- a/urdf/canadarm2.urdf.xacro +++ b/urdf/canadarm2.urdf.xacro @@ -1,7 +1,9 @@ - + + + @@ -12,12 +14,11 @@ - - - + + @@ -35,16 +36,15 @@ - - - - + + + - + @@ -58,16 +58,15 @@ - - - + + - + @@ -80,13 +79,12 @@ - - + - - - + + + @@ -104,13 +102,11 @@ - - - - - + + + @@ -128,12 +124,11 @@ - - - - + + + @@ -150,13 +145,12 @@ - - + - - + + @@ -174,12 +168,11 @@ - - - + + @@ -195,84 +188,102 @@ - + - - + - - + - + - - + - - + - - + - - - - + + + - - - - + + + - - - - + + + - - - - - - + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/urdf/dextre.urdf.xacro b/urdf/dextre.urdf.xacro index 2e6ca47..69b1d9e 100644 --- a/urdf/dextre.urdf.xacro +++ b/urdf/dextre.urdf.xacro @@ -1,6 +1,9 @@ + + + @@ -99,7 +102,7 @@ - + @@ -107,14 +110,14 @@ - + - + @@ -134,7 +137,7 @@ - + @@ -156,7 +159,7 @@ - + @@ -179,7 +182,7 @@ - + @@ -202,7 +205,7 @@ - + @@ -225,7 +228,7 @@ - + @@ -248,7 +251,7 @@ - + @@ -271,12 +274,12 @@ - + - + @@ -335,7 +338,7 @@ - + @@ -357,7 +360,7 @@ - + @@ -380,7 +383,7 @@ - + @@ -404,7 +407,7 @@ - + @@ -427,8 +430,8 @@ - - + + @@ -450,7 +453,7 @@ - + @@ -474,11 +477,11 @@ - + - + @@ -498,7 +501,7 @@ - + @@ -534,8 +537,36 @@ - + + + + + + + + + + + + + + + - + diff --git a/urdf/etvcg_cameras.urdf.xacro b/urdf/etvcg_cameras.urdf.xacro new file mode 100644 index 0000000..a03dd77 --- /dev/null +++ b/urdf/etvcg_cameras.urdf.xacro @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/urdf/mobile_servicing_system.gazebo.xacro b/urdf/mobile_servicing_system.gazebo.xacro index c65c5ea..9c17336 100644 --- a/urdf/mobile_servicing_system.gazebo.xacro +++ b/urdf/mobile_servicing_system.gazebo.xacro @@ -5,7 +5,8 @@ - + + @@ -13,10 +14,20 @@ gz_ros2_control/GazeboSimSystem - + - + + + + + + + + + + + @@ -28,42 +39,7 @@ - - - - - - - - - - - - - 1 - 10.0 - - 1.0 0 0 0 0 -1.57 - 1.3962634 - - 800 - 800 - R8G8B8 - - - 0.01 - 100 - - - gaussian - 0.007 - - - 1 - image_raw - - - + diff --git a/urdf/pt_camera.gazebo.xacro b/urdf/pt_camera.gazebo.xacro new file mode 100644 index 0000000..2cda977 --- /dev/null +++ b/urdf/pt_camera.gazebo.xacro @@ -0,0 +1,111 @@ + + + + + + + + + + ${horizontal_fov} + + ${image_width} + ${image_height} + ${image_format} + + + ${clip_near} + ${clip_far} + + + 1 + ${update_rate} + true + ${prefix}/image_raw + ${prefix}_optical_frame + + + + ${sun_light_name} + ${lens_flare_scale} + ${lens_flare_color} + ${lens_flare_occlusion_steps} + + + + + + + + Gazebo/Black + + + + + Gazebo/DarkGrey + + + + + Gazebo/Grey + + + + + + + + + + + + + + + + + + + diff --git a/urdf/pt_camera.urdf.xacro b/urdf/pt_camera.urdf.xacro new file mode 100644 index 0000000..a2025ce --- /dev/null +++ b/urdf/pt_camera.urdf.xacro @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/worlds/leo.sdf b/worlds/leo.sdf index 036622b..d9a197e 100644 --- a/worlds/leo.sdf +++ b/worlds/leo.sdf @@ -1,14 +1,33 @@ + 0.4 0.4 0.4 1 - 0.0 0.0 0.0 1 + 0 0 0 1 + true false - + + + + true + 0 0 10000 0 0 0 + + + + 0 0 0 0 0 0 + true + 0 0 -1 + 1.0 1.0 1.0 1 + 1.0 1.0 1.0 1 + 2.0 + + + + - + @@ -16,7 +35,6 @@ false docked - ogre2 scene -10.0 -12 8.0 0 0.5 0.3 @@ -39,66 +57,29 @@ false - + floating - - + + - + 0.01 1 100 - - - - - - - - - - + + + + ogre2 - - - true - 0 -10 10 0 0 0 - 0.8 0.8 0.8 1 - 0.2 0.2 0.2 1 - - 1000 - 0.9 - 0.01 - 0.001 - - 10 10 -0.9 - 0 0 0 - - - - - - + \ No newline at end of file