Class: Rclrb::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/rclrb/client.rb

Overview

Represent a ROS client

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(client_handle, node_handle, srv_type, srv_name, qos_profile) ⇒ Client

Construct a new publisher, this should not be called directly, instead use Node.create_publisher.



7
8
9
10
11
12
13
14
15
16
17
18
19
# File 'lib/rclrb/client.rb', line 7

def initialize(client_handle, node_handle, srv_type, srv_name, qos_profile)
  @client_handle = client_handle
  @node_handle = node_handle
  @srv_type = srv_type
  @srv_name = srv_name
  @qos_profile = qos_profile
  @call_counter = 0

  client_ops = CApi.rcl_client_get_default_options()
  client_ops[:qos] = QoSProfile.get_profile(qos_profile).ros_profile
  CApi.handle_result CApi.rcl_client_init(@client_handle, node_handle, srv_type.type_support(), @srv_name, client_ops)
  Rclrb.rcl_signal_guard_condition.trigger
end

Instance Attribute Details

#client_handleObject (readonly)

Returns the value of attribute client_handle.



5
6
7
# File 'lib/rclrb/client.rb', line 5

def client_handle
  @client_handle
end

#srv_typeObject (readonly)

Returns the value of attribute srv_type.



5
6
7
# File 'lib/rclrb/client.rb', line 5

def srv_type
  @srv_type
end

Instance Method Details

#call_async(request) ⇒ Object

Call a service asynchronously with the given request, it will return a Future object.

Raises:



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
# File 'lib/rclrb/client.rb', line 27

def call_async(request)
  raise RclError.new unless request.kind_of? @srv_type::Request
  
  counter = CApi::Int64Ptr.new
  counter[:value] = (@call_counter += 1)
  future = Future.execute do
    ros_req = @srv_type::Request.get_ros_message request
    CApi.handle_result CApi.rcl_send_request(@client_handle, ros_req, counter), lambda { @srv_type::Request.destroy_ros_message(ros_req)}
    ros_resp = @srv_type::Response::FFIType.new
    info = CApi::RmwServiceInfoT.new
    waiting_for_answer = true
    wait_set = WaitSet.new
    wait_set.add self
    while waiting_for_answer
      wait_set.wait
      status = CApi.rcl_take_response_with_info @client_handle, info, ros_resp
      if status == CApi::RCL_RET_OK
        response = @srv_type::Response.parse_ros_message ros_resp
        @srv_type::Response.destroy_ros_message ros_resp
        waiting_for_answer = false
      elsif status == CApi::RCL_RET_CLIENT_TAKE_FAILED
        raise ServiceCallFailed.new
      else
        CApi.handle_result status
      end
      if Rclrb.rcl_shutdown_requested?
        raise InterruptedClientCall.new "Call to #{@srv_name} was interrupted by shutdown"
      end
    end
    response
  end
  return future
end

#service_is_readyObject

Return true if the service is available.



73
74
75
76
77
# File 'lib/rclrb/client.rb', line 73

def service_is_ready
  b = CApi::BoolPtr.new
  CApi.handle_result CApi.rcl_service_server_is_available @node_handle, @client_handle, b
  return b[:value]
end

#wait_for_service(timeout_sec = nil) ⇒ Object

Wait for the service to be available. If timeout_sec is nil, it will wait forever, otherwise it will timeout when the amount of time specified by timeout_sec has expired.



63
64
65
66
67
68
69
70
71
# File 'lib/rclrb/client.rb', line 63

def wait_for_service(timeout_sec=nil)
  sleep_time = 0.25
  timeout_sec = Float::INFINITY if timeout_sec.nil?
  until Rclrb.rcl_shutdown_requested? or self.service_is_ready() or timeout_sec < 0.0
    sleep(sleep_time)
    timeout_sec -= sleep_time
  end
  return self.service_is_ready
end