Skip to content

Commit 87e88c8

Browse files
authored
fix ros2action send_goal signal handling. (#1072)
Signed-off-by: Tomoya Fujita <[email protected]>
1 parent e4e86fe commit 87e88c8

File tree

1 file changed

+25
-2
lines changed

1 file changed

+25
-2
lines changed

ros2action/ros2action/verb/send_goal.py

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15+
from argparse import ArgumentTypeError
16+
1517
import signal
1618

1719
from action_msgs.msg import GoalStatus
@@ -30,6 +32,16 @@
3032
import yaml
3133

3234

35+
def non_negative_int(string):
36+
try:
37+
value = int(string)
38+
except ValueError:
39+
value = -1
40+
if value < 0:
41+
raise ArgumentTypeError('value must not be a negative integer')
42+
return value
43+
44+
3345
class SendGoalVerb(VerbExtension):
3446
"""Send an action goal."""
3547

@@ -54,7 +66,7 @@ def add_arguments(self, parser, cli_name):
5466
'-f', '--feedback', action='store_true',
5567
help='Echo feedback messages for the goal')
5668
parser.add_argument(
57-
'-t', '--timeout', metavar='N', type=int, default=None,
69+
'-t', '--timeout', metavar='N', type=non_negative_int, default=None,
5870
help=(
5971
'Wait for N seconds until server becomes available and goal is completed '
6072
'(default waits indefinitely)'
@@ -176,7 +188,18 @@ def _sigint_cancel_handler(sig, frame):
176188
print('Goal accepted with ID: {}\n'.format(bytes(goal_handle.goal_id.uuid).hex()))
177189

178190
result_future = goal_handle.get_result_async()
179-
rclpy.spin_until_future_complete(node, result_future, timeout_sec=timeout)
191+
if timeout == 0:
192+
# Not waiting for the result, just return immediately
193+
rclpy.spin_until_future_complete(node, result_future, timeout_sec=0)
194+
else:
195+
elapsed_time = 0
196+
while rclpy.ok() and not result_future.done():
197+
# Spin until the result is available or timeout occurs
198+
# To trigger the signal handler, it calls spin_until_future_complete with 1 second
199+
elapsed_time += 1
200+
rclpy.spin_until_future_complete(node, result_future, timeout_sec=1)
201+
if timeout is not None and elapsed_time >= timeout:
202+
break
180203

181204
if not result_future.done():
182205
print(f'Timed out waiting for result after {timeout} seconds.')

0 commit comments

Comments
 (0)