본문 바로가기
기계공학부 시절의 기록/ROS2 Study

11 week HW (1) action programming : action client node

by juhyeonglee 2021. 11. 14.
728x90
반응형

1. write "fibonacci_action_client.py" code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
import rclpy
 
# import ActionClient class to make actionclient
from rclpy.action import ActionClient
from rclpy.node import Node
 
# import Fibonacci interface type
from my_interface_example.action import Fibonacci
 
class FibonacciActionClient(Node):
 
    def __init__(self):
        # Initialize FibonacciActionClientclass by calling Node & make node name
        super().__init__('fibonacci_action_client')
 
        # the action client is created by ActionClient class
        self._action_client = ActionClient(
            self,
            Fibonacci,
            'fibonacci')
 
    def send_goal(self, order):
        goal_msg = Fibonacci.Goal()
        goal_msg.order = order
 
        # waits for the action server to be available
        self._action_client.wait_for_server()
 
        # send a goal to the server
        return self._action_client.send_goal_async(goal_msg)
 
        # to get result
        #self._send_goal_future = self._action_client.send_goal_async(goal_msg)
        #self._send_goal_future.add_done_callback(self.goal_response_callback)
 
    def goal_response_callback(self, future):
        goal_handle = future.result()
        if not goal_handle.accepted:
            self.get_logger().info('Goal rejected')
            return
 
        self.get_logger().info('Goal accepted')
 
        self._get_result_future = goal_handle
 
def main(args=None):
    rclpy.init(args=args)
 
    action_client = FibonacciActionClient()
 
    future = action_client.send_goal(10)
 
    rclpy.spin_until_future_complete(action_client, future)
 
if __name__ == '__main__':
    main()
cs

 

2. test node

1) $ python3 fibonacci_action_server.py

2) at a new terminal

$ python3 fibonacci_action_client.py

 

we cant see any message on client node terminal

 

 

3. revise code to get result

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
import rclpy
 
# import ActionClient class to make actionclient
from rclpy.action import ActionClient
from rclpy.node import Node
 
# import Fibonacci interface type
from my_interface_example.action import Fibonacci
 
class FibonacciActionClient(Node):
 
    def __init__(self):
        # Initialize FibonacciActionClientclass by calling Node & make node name
        super().__init__('fibonacci_action_client')
 
        # the action client is created by ActionClient class
        self._action_client = ActionClient(
            self,
            Fibonacci,
            'fibonacci')
 
    def send_goal(self, order):
        goal_msg = Fibonacci.Goal()
        goal_msg.order = order
 
        # waits for the action server to be available
        self._action_client.wait_for_server()
 
        # send a goal to the server
        # return self._action_client.send_goal_async(goal_msg)
 
        # to get result
        # send a goal to the server
        self._send_goal_future = self._action_client.send_goal_async(goal_msg)
 
        # the callback func. is called when future is completed. what is future??
        # 'future is completed' means that goal request is accepted or rejected !!
        self._send_goal_future.add_done_callback(self.goal_response_callback)
 
    def goal_response_callback(self, future):
        # future.result() returns goal_handle that is the instance of ClientGoalHandle class
        goal_handle = future.result()
 
        # check the goal was rejected or accepted
        if not goal_handle.accepted:
            self.get_logger().info('Goal rejected')
            return
 
        self.get_logger().info('Goal accepted')
 
        # requests the goal result asynchronously
        self._get_result_future = goal_handle.get_result_async()
        # get_result_callback func is called when future is completed
        self._get_result_future.add_done_callback(self.get_result_callback)
 
    def get_result_callback(self, future):
        result = future.result().result
 
        # print the result sequence
        self.get_logger().info('Result: {0}'.format(result.sequence))
 
        # shutdown the client node
        rclpy.shutdown()
 
def main(args=None):
    rclpy.init(args=args)
 
    action_client = FibonacciActionClient()
 
    future = action_client.send_goal(10)
 
    # rclpy.spin_until_future_complete(action_client, future)
 
    rclpy.spin(action_client)
if __name__ == '__main__':
    main()
cs
 
 

 

# future.result() returns goal_handle that is the instance of ClientGoalHandle class
goal_handle = future.result()

 

ClientGoalHandle class(rosdoc)

at this class, what is property?

 

 

4. test

1) $ python3 fibonacci_action_server.py

2) at a new terminal

$ python3 fibonacci_action_client.py

 

we can see the result message on client node terminal

 

5. revise code to get feedback

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# This actionClient node sends goal and recieve feedback and result
 
import rclpy
 
# import ActionClient class to make actionclient
from rclpy.action import ActionClient
from rclpy.node import Node
 
# import Fibonacci interface type
from my_interface_example.action import Fibonacci
 
class FibonacciActionClient(Node):
 
    def __init__(self):
        # Initialize FibonacciActionClientclass by calling Node & make node name
        super().__init__('fibonacci_action_client')
 
        # the action client is created by ActionClient class
        self._action_client = ActionClient(
            self,
            Fibonacci,
            'fibonacci')
 
    def send_goal(self, order):
        goal_msg = Fibonacci.Goal()
        goal_msg.order = order
 
        # waits for the action server to be available
        self._action_client.wait_for_server()
 
        # send a goal to the server
        # return self._action_client.send_goal_async(goal_msg)
 
        # to get result
        # send a goal to the server
        # self._send_goal_future = self._action_client.send_goal_async(goal_msg)
 
 
        # to get feedback
        self._send_goal_future = self._action_client.send_goal_async(goal_msg, feedback_callback=self.feedback_callback)
 
        # the callback func. is called when future is completed. what is future??
        # 'future is completed' means that goal request is accepted or rejected !!
        self._send_goal_future.add_done_callback(self.goal_response_callback)
 
 
    def goal_response_callback(self, future):
        # future.result() returns goal_handle that is the instance of ClientGoalHandle class
        goal_handle = future.result()
 
        # check the goal was rejected or accepted
        if not goal_handle.accepted:
            self.get_logger().info('Goal rejected')
            return
 
        self.get_logger().info('Goal accepted')
 
        # requests the goal result asynchronously
        self._get_result_future = goal_handle.get_result_async()
        # get_result_callback func is called when future is completed
        self._get_result_future.add_done_callback(self.get_result_callback)
 
    def get_result_callback(self, future):
        result = future.result().result
 
        # print the result sequence
        self.get_logger().info('Result: {0}'.format(result.sequence))
 
        # shutdown the client node
        rclpy.shutdown()
 
    def feedback_callback(self, feedback_msg):
        feedback = feedback_msg.feedback
        # when the feedback is received, partial_sequence is printed
        self.get_logger().info('Received feedback: {0}'.format(feedback.partial_sequence))
        #rclpy.shutdown()
 
def main(args=None):
    rclpy.init(args=args)
 
    action_client = FibonacciActionClient()
 
    future = action_client.send_goal(10)
 
    # rclpy.spin_until_future_complete(action_client, future)
 
    rclpy.spin(action_client)
if __name__ == '__main__':
    main()
cs

 

 

6. test

 

we can see the feedback and result

 

7. build package

1) revise the package.xml file

2) revise the setup.py file

build and run 2 nodes

 

728x90
반응형

댓글