Browse Source

Merge changes.

main
Alan G. Sanchez 2 years ago
parent
commit
e99551e0b8
9 changed files with 308 additions and 88 deletions
  1. +1
    -1
      aruco_marker_detection.md
  2. +1
    -1
      follow_joint_trajectory.md
  3. +89
    -79
      rviz/aruco_detector_example.rviz
  4. +209
    -0
      src/docking_station_locator.py
  5. +2
    -2
      src/effort_sensing.py
  6. +2
    -2
      src/joint_state_printer.py
  7. +1
    -0
      src/scan_filter.py
  8. +1
    -1
      src/single_joint_actuator.py
  9. +2
    -2
      src/voice_teleoperation_base.py

+ 1
- 1
aruco_marker_detection.md View File

@ -131,4 +131,4 @@ When coming up with this guide, we expected the following:
* Body-mounted accessories with the same ID numbers mounted to different robots could be disambiguated using the expected range of 3D locations of the ArUco markers on the calibrated body.
* Accessories in the environment with the same ID numbers could be disambiguated using a map or nearby observable features of the environment.
**Next Tutorial:** [ReSpeaker Microphone Array](respeaker_mircophone_array.md)
**Next Tutorial:** [ReSpeaker Microphone Array](respeaker_microphone_array.md)

+ 1
- 1
follow_joint_trajectory.md View File

@ -298,7 +298,7 @@ You can also actuate a single joint for the Stretch. Below are the list of joint
joint_lift: lower_limit = 0.15, upper_limit = 1.10 # in meters
wrist_extension: lower_limit = 0.00, upper_limit = 0.50 # in meters
joint_wrist_yaw: lower_limit = -1.75, upper_limit = 4.00 # in radians
joint_head_pan: lower_limit = -2.80, upper_limit = 2.90 # in radians
joint_head_pan: lower_limit = -4.10, upper_limit = 1.60 # in radians
joint_head_tilt: lower_limit = -1.60, upper_limit = 0.40 # in radians
joint_gripper_finger_left: lower_limit = -0.35, upper_limit = 0.165 # in radians

+ 89
- 79
rviz/aruco_detector_example.rviz View File

@ -7,10 +7,8 @@ Panels:
- /Status1
- /RobotModel1
- /RobotModel1/Links1/camera_bottom_screw_frame1
- /TF1
- /TF1/Frames1
Splitter Ratio: 0.8150289058685303
Tree Height: 915
Splitter Ratio: 0.5058823823928833
Tree Height: 366
- Class: rviz/Selection
Name: Selection
- Class: rviz/Tool Properties
@ -29,7 +27,7 @@ Panels:
Experimental: false
Name: Time
SyncMode: 0
SyncSource: PointCloud2
SyncSource: Image
Preferences:
PromptSaveOnExit: true
Toolbars:
@ -295,12 +293,8 @@ Visualization Manager:
Frame Timeout: 15
Frames:
All Enabled: false
base_left:
Value: true
base_link:
Value: false
base_right:
Value: true
camera_accel_frame:
Value: false
camera_accel_optical_frame:
@ -313,10 +307,16 @@ Visualization Manager:
Value: false
camera_color_optical_frame:
Value: false
camera_color_optical_frame_rotated:
Value: false
camera_depth_frame:
Value: false
camera_depth_optical_frame:
Value: false
camera_gyro_frame:
Value: false
camera_gyro_optical_frame:
Value: false
camera_infra1_frame:
Value: false
camera_infra1_optical_frame:
@ -327,6 +327,8 @@ Visualization Manager:
Value: false
camera_link:
Value: false
docking_station:
Value: true
laser:
Value: false
link_arm_l0:
@ -377,89 +379,95 @@ Visualization Manager:
Value: false
link_wrist_yaw:
Value: false
odom:
Value: true
respeaker_base:
Value: false
shoulder_top:
Value: true
wrist_inside:
Value: true
wrist_top:
Value: true
Marker Scale: 1
Name: TF
Show Arrows: true
Show Axes: true
Show Names: true
Tree:
base_link:
laser:
{}
link_aruco_left_base:
{}
link_aruco_right_base:
{}
link_left_wheel:
{}
link_mast:
link_head:
link_head_pan:
link_head_tilt:
camera_bottom_screw_frame:
camera_link:
camera_accel_frame:
camera_accel_optical_frame:
odom:
base_link:
laser:
{}
link_aruco_left_base:
{}
link_aruco_right_base:
{}
link_left_wheel:
{}
link_mast:
link_head:
link_head_pan:
link_head_tilt:
camera_bottom_screw_frame:
camera_link:
camera_accel_frame:
camera_accel_optical_frame:
{}
camera_aligned_depth_to_color_frame:
camera_color_optical_frame:
camera_color_optical_frame_rotated:
{}
docking_station:
{}
camera_color_frame:
{}
camera_aligned_depth_to_color_frame:
{}
camera_color_frame:
camera_color_optical_frame:
base_left:
camera_depth_frame:
camera_depth_optical_frame:
{}
base_right:
camera_gyro_frame:
camera_gyro_optical_frame:
{}
shoulder_top:
camera_infra1_frame:
camera_infra1_optical_frame:
{}
wrist_inside:
camera_infra2_frame:
camera_infra2_optical_frame:
{}
wrist_top:
link_lift:
link_arm_l4:
link_arm_l3:
link_arm_l2:
link_arm_l1:
link_arm_l0:
link_aruco_inner_wrist:
{}
camera_depth_frame:
camera_depth_optical_frame:
{}
camera_infra1_frame:
camera_infra1_optical_frame:
{}
camera_infra2_frame:
camera_infra2_optical_frame:
{}
link_lift:
link_arm_l4:
link_arm_l3:
link_arm_l2:
link_arm_l1:
link_arm_l0:
link_aruco_inner_wrist:
{}
link_aruco_top_wrist:
{}
link_wrist_yaw:
link_gripper:
link_grasp_center:
{}
link_gripper_finger_left:
link_gripper_fingertip_left:
{}
link_gripper_finger_right:
link_gripper_fingertip_right:
link_aruco_top_wrist:
{}
link_wrist_yaw:
link_gripper:
link_grasp_center:
{}
link_aruco_shoulder:
link_gripper_finger_left:
link_gripper_fingertip_left:
{}
link_gripper_finger_right:
link_gripper_fingertip_right:
{}
link_aruco_shoulder:
{}
respeaker_base:
{}
respeaker_base:
link_right_wheel:
{}
link_right_wheel:
{}
Update Interval: 0
Value: true
- Class: rviz/Image
Enabled: true
Image Topic: /camera/color/upright_image_raw
Max Value: 1
Median window: 5
Min Value: 0
Name: Image
Normalize Range: true
Queue Size: 2
Transport Hint: raw
Unreliable: false
Value: true
Enabled: true
Global Options:
Background Color: 48; 48; 48
@ -488,7 +496,7 @@ Visualization Manager:
Views:
Current:
Class: rviz/Orbit
Distance: 2.342942714691162
Distance: 4.624553680419922
Enable Stereo Rendering:
Stereo Eye Separation: 0.05999999865889549
Stereo Focal Distance: 1
@ -503,10 +511,10 @@ Visualization Manager:
Invert Z Axis: false
Name: Current View
Near Clip Distance: 0.009999999776482582
Pitch: 0.37479761242866516
Pitch: 0.4497976303100586
Target Frame: <Fixed Frame>
Value: Orbit (rviz)
Yaw: 3.980466365814209
Yaw: 3.255469799041748
Saved: ~
Window Geometry:
Displays:
@ -514,7 +522,9 @@ Window Geometry:
Height: 1212
Hide Left Dock: false
Hide Right Dock: false
QMainWindow State: 000000ff00000000fd0000000400000000000001a20000041efc020000000bfb0000001200530065006c0065006300740069006f006e00000001e10000009b0000005c00fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed000001df00000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c006100790073010000003d0000041e000000c900fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261fb0000000c00430061006d006500720061000000022f000000c70000000000000000fb0000000a0049006d00610067006500000002920000026d0000000000000000fb0000000c00430061006d0065007200610000000429000000d60000000000000000000000010000010f00000363fc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a00560069006500770073000000003d00000363000000a400fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e100000197000000030000056f0000003efc0100000002fb0000000800540069006d006501000000000000056f000002eb00fffffffb0000000800540069006d00650100000000000004500000000000000000000003c70000041e00000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000
Image:
collapsed: false
QMainWindow State: 000000ff00000000fd0000000400000000000002aa0000041efc020000000cfb0000001200530065006c0065006300740069006f006e00000001e10000009b0000005c00fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed000001df00000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c006100790073010000003d000001f9000000c900fffffffb0000000a0049006d006100670065010000023c0000021f0000001600fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261fb0000000c00430061006d006500720061000000022f000000c70000000000000000fb0000000a0049006d00610067006500000002920000026d0000000000000000fb0000000c00430061006d0065007200610000000429000000d60000000000000000000000010000010f00000363fc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a00560069006500770073000000003d00000363000000a400fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e100000197000000030000056f0000003efc0100000002fb0000000800540069006d006501000000000000056f000002eb00fffffffb0000000800540069006d00650100000000000004500000000000000000000002bf0000041e00000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000
Selection:
collapsed: false
Time:
@ -524,5 +534,5 @@ Window Geometry:
Views:
collapsed: false
Width: 1391
X: 1030
Y: 84
X: 242
Y: 92

+ 209
- 0
src/docking_station_locator.py View File

@ -0,0 +1,209 @@
#! /usr/bin/env python
# Import modules
import rospy
import time
import tf2_ros
import numpy as np
from math import pi
# Import hello_misc script for handling trajectory goals with an action client
import hello_helpers.hello_misc as hm
# We're going to subscribe to a JointState message type, so we need to import
# the definition for it
from sensor_msgs.msg import JointState
# Import the FollowJointTrajectoryGoal from the control_msgs.msg package to
# control the Stretch robot.
from control_msgs.msg import FollowJointTrajectoryGoal
# Import JointTrajectoryPoint from the trajectory_msgs package to define
# robot trajectories.
from trajectory_msgs.msg import JointTrajectoryPoint
# Import TransformStamped from the geometry_msgs package for the publisher
from geometry_msgs.msg import TransformStamped
class LocateDockingTag(hm.HelloNode):
"""
A class that actuates the RealSense camera to find the docking station using
an ArUco tag.
"""
def __init__(self):
"""
A function that initializes the subscriber and other needed variables.
:param self: The self reference.
"""
# Initialize the inhereted hm.Hellonode class
hm.HelloNode.__init__(self)
# Initialize Subscriber
self.joint_states_sub = rospy.Subscriber('/stretch/joint_states', JointState, self.joint_states_callback)
# Initialize publisher
self.transform_pub = rospy.Publisher('ArUco_transform', TransformStamped, queue_size=10)
# Initialize the variable that will store the joint state positions
self.joint_state = None
# Provide the min and max joint positions for the head pan. These values
# are needed for sweeping the head to search for the ArUco tag.
self.min_pan_position = -4.10
self.max_pan_position = 1.50
# Define the number of steps for the sweep, then create the step size for
# the head pan joint.
self.pan_num_steps = 10
self.pan_step_size = abs(self.min_pan_position - self.max_pan_position)/self.pan_num_steps
# Define the min tilt position, number of steps, and step size.
self.min_tilt_position = -0.75
self.tilt_num_steps = 3
self.tilt_step_size = pi/16
def joint_states_callback(self, msg):
"""
A callback function that stores Stretch's joint states.
:param self: The self reference.
:param msg: The JointState message type.
"""
self.joint_state = msg
def send_command(self, command):
'''
Handles single joint control commands by constructing a FollowJointTrajectoryGoal message and sending it to the trajectory_client
created in hello_misc.
:param self: The self reference.
:param command: A dictionary message type.
'''
if (self.joint_state is not None) and (command is not None):
# Extract the string value from the `joint` key
joint_name = command['joint']
# Set trajectory_goal as a FollowJointTrajectoryGoal and define
# the joint name
trajectory_goal = FollowJointTrajectoryGoal()
trajectory_goal.trajectory.joint_names = [joint_name]
# Set positions for the following 5 trajectory points
point = JointTrajectoryPoint()
# Check to see if `delta` is a key in the command dictionary
if 'delta' in command:
# Get the current position of the joint and add the delta as a
# new position value
joint_index = self.joint_state.name.index(joint_name)
joint_value = self.joint_state.position[joint_index]
delta = command['delta']
new_value = joint_value + delta
point.positions = [new_value]
# Check to see if `position` is a key in the command dictionary
elif 'position' in command:
# extract the head position value from the `position` key
point.positions = [command['position']]
# Assign goal position with updated point variable
trajectory_goal.trajectory.points = [point]
# Specify the coordinate frame that we want (base_link) and set the time to be now.
trajectory_goal.trajectory.header.stamp = rospy.Time(0.0)
trajectory_goal.trajectory.header.frame_id = 'base_link'
# Make the action call and send the goal. The last line of code waits
# for the result
self.trajectory_client.send_goal(trajectory_goal)
self.trajectory_client.wait_for_result()
def find_tag(self, tag_name='docking_station'):
"""
A function that actuates the camera to search for a defined ArUco tag
marker. Then the function returns the pose
:param self: The self reference.
:param tag_name: A string value of the ArUco marker name.
:returns transform: A TransformStamped message type.
"""
# Create a dictionaries to get the head in its initial position for its search
pan_command = {'joint': 'joint_head_pan', 'position': self.min_pan_position}
self.send_command(pan_command)
tilt_command = {'joint': 'joint_head_tilt', 'position': self.min_tilt_position}
self.send_command(tilt_command)
# Nested for loop to sweep the pan and tilt in increments
for i in range(self.tilt_num_steps):
for j in range(self.pan_num_steps):
# Update the joint_head_pan position by the pan_step_size
pan_command = {'joint': 'joint_head_pan', 'delta': self.pan_step_size}
self.send_command(pan_command)
# Give time for system to do a Transform lookup before next step
rospy.sleep(0.5)
# Use a try-except block
try:
# Look up transform between the base_link and located ArUco tag
transform = self.tf_buffer.lookup_transform('base_link',
tag_name,
rospy.Time())
rospy.loginfo("Found Requested Tag: \n%s", transform)
# Publish the transform
self.transform_pub.publish(transform)
# Return the transform
return transform
except (tf2_ros.LookupException, tf2_ros.ConnectivityException, tf2_ros.ExtrapolationException):
continue
# Begin sweep with new tilt angle
pan_command = {'joint': 'joint_head_pan', 'position': self.min_pan_position}
self.send_command(pan_command)
tilt_command = {'joint': 'joint_head_tilt', 'delta': self.tilt_step_size}
self.send_command(tilt_command)
rospy.sleep(.25)
def main(self):
"""
Function that initiates the issue_command function.
:param self: The self reference.
"""
# The arguments of the main function of the hm.HelloNode class are the
# node_name, node topic namespace, and boolean (default value is true)
hm.HelloNode.main(self, 'docking_station_locator', 'docking_station_locator', wait_for_first_pointcloud=False)
# Create a StaticTranformBoradcaster Node. Also, start a Tf buffer that
# will store the tf information for a few seconds.Then set up a tf listener, which
# will subscribe to all of the relevant tf topics, and keep track of the information.
self.static_broadcaster = tf2_ros.StaticTransformBroadcaster()
self.tf_buffer = tf2_ros.Buffer()
self.listener = tf2_ros.TransformListener(self.tf_buffer)
# Give the listener some time to accumulate transforms
rospy.sleep(1.0)
# Notify Stretch is searchring for the ArUco tag with a rospy loginfo fucntion
rospy.loginfo('Searching for docking ArUco tag.')
# Search for the ArUco marker for the docking station
pose = self.find_tag("docking_station")
if __name__ == '__main__':
# Instantiate the `LocateDockingTag()` object
node = LocateDockingTag()
# Run the `main()` method.
node.main()
# Use a try-except block
try:
rospy.spin()
except KeyboardInterrupt:
rospy.loginfo('interrupt received, so shutting down')

+ 2
- 2
src/effort_sensing.py View File

@ -15,8 +15,8 @@ from control_msgs.msg import FollowJointTrajectoryGoal
# robot trajectories.
from trajectory_msgs.msg import JointTrajectoryPoint
# We're going to subscribe to 64-bit integers, so we need to import the definition
# for them.
# We're going to subscribe to a JointState message type, so we need to import
# the definition for it
from sensor_msgs.msg import JointState
# Import hello_misc script for handling trajecotry goals with an action client.

+ 2
- 2
src/joint_state_printer.py View File

@ -4,8 +4,8 @@
import rospy
import sys
# We're going to subscribe to 64-bit integers, so we need to import the definition
# for them
# We're going to subscribe to a JointState message type, so we need to import
# the definition for it
from sensor_msgs.msg import JointState
class JointStatePublisher():

+ 1
- 0
src/scan_filter.py View File

@ -4,6 +4,7 @@
import rospy
from numpy import linspace, inf
from math import sin
# We're going to subscribe to a LaserScan message
from sensor_msgs.msg import LaserScan

+ 1
- 1
src/single_joint_actuator.py View File

@ -34,7 +34,7 @@ class SingleJointActuator(hm.HelloNode):
# joint_lift: lower_limit = 0.15, upper_limit = 1.10 # in meters
# wrist_extension: lower_limit = 0.00, upper_limit = 0.50 # in meters
# joint_wrist_yaw: lower_limit = -1.75, upper_limit = 4.00 # in radians
# joint_head_pan: lower_limit = -2.80, upper_limit = 2.90 # in radians
# joint_head_pan: lower_limit = -4.10, upper_limit = 1.60 # in radians
# joint_head_tilt: lower_limit = -1.60, upper_limit = 0.40 # in radians
# joint_gripper_finger_left: lower_limit = -0.35, upper_limit = 0.165 # in radians
#

+ 2
- 2
src/voice_teleoperation_base.py View File

@ -5,8 +5,8 @@ import math
import rospy
import sys
# We're going to subscribe to 64-bit integers, so we need to import the definition
# for them
# We're going to subscribe to a JointState message type, so we need to import
# the definition for it
from sensor_msgs.msg import JointState
# Import Int32 message typs from the std_msgs package

Loading…
Cancel
Save