rosruby 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. data/bin/rubyroscore +5 -0
  2. data/lib/ros.rb +25 -0
  3. data/lib/ros/duration.rb +63 -0
  4. data/lib/ros/graph_manager.rb +408 -0
  5. data/lib/ros/log.rb +72 -0
  6. data/lib/ros/master.rb +408 -0
  7. data/lib/ros/master_proxy.rb +256 -0
  8. data/lib/ros/message.rb +65 -0
  9. data/lib/ros/name.rb +88 -0
  10. data/lib/ros/node.rb +442 -0
  11. data/lib/ros/package.rb +144 -0
  12. data/lib/ros/parameter_manager.rb +127 -0
  13. data/lib/ros/parameter_subscriber.rb +47 -0
  14. data/lib/ros/publisher.rb +96 -0
  15. data/lib/ros/rate.rb +41 -0
  16. data/lib/ros/ros.rb +10 -0
  17. data/lib/ros/roscore.rb +29 -0
  18. data/lib/ros/service.rb +37 -0
  19. data/lib/ros/service_client.rb +83 -0
  20. data/lib/ros/service_server.rb +92 -0
  21. data/lib/ros/slave_proxy.rb +153 -0
  22. data/lib/ros/subscriber.rb +119 -0
  23. data/lib/ros/tcpros/client.rb +108 -0
  24. data/lib/ros/tcpros/header.rb +89 -0
  25. data/lib/ros/tcpros/message.rb +74 -0
  26. data/lib/ros/tcpros/server.rb +137 -0
  27. data/lib/ros/tcpros/service_client.rb +104 -0
  28. data/lib/ros/tcpros/service_server.rb +132 -0
  29. data/lib/ros/time.rb +109 -0
  30. data/lib/ros/topic.rb +47 -0
  31. data/lib/ros/xmlrpcserver.rb +40 -0
  32. data/samples/add_two_ints_client.rb +25 -0
  33. data/samples/add_two_ints_server.rb +20 -0
  34. data/samples/gui.rb +126 -0
  35. data/samples/sample_log.rb +16 -0
  36. data/samples/sample_param.rb +20 -0
  37. data/samples/sample_publisher.rb +20 -0
  38. data/samples/sample_subscriber.rb +19 -0
  39. data/scripts/genmsg_ruby.py +1135 -0
  40. data/scripts/genmsg_ruby.pyc +0 -0
  41. data/scripts/gensrv_ruby.py +105 -0
  42. data/scripts/gensrv_ruby.pyc +0 -0
  43. data/scripts/rosruby_genmsg.py +67 -0
  44. data/scripts/run-test.rb +21 -0
  45. data/test/test_header.rb +36 -0
  46. data/test/test_log.rb +45 -0
  47. data/test/test_master_proxy.rb +73 -0
  48. data/test/test_message.rb +13 -0
  49. data/test/test_node.rb +166 -0
  50. data/test/test_package.rb +10 -0
  51. data/test/test_param.rb +27 -0
  52. data/test/test_pubsub.rb +154 -0
  53. data/test/test_rate.rb +16 -0
  54. data/test/test_service.rb +34 -0
  55. data/test/test_slave_proxy.rb +49 -0
  56. data/test/test_time.rb +39 -0
  57. metadata +170 -0
@@ -0,0 +1,144 @@
1
+ # ros/package.rb
2
+ #
3
+ # License: BSD
4
+ #
5
+ # Copyright (C) 2012 Takashi Ogura <t.ogura@gmail.com>
6
+ #
7
+ # == ROS Package manager
8
+ #
9
+ # This is used for adding RUBYLIB path.
10
+ # This file will provide rospack functions, in the future
11
+ #
12
+
13
+ require 'rexml/document'
14
+
15
+ module ROS
16
+
17
+ # This is used for adding RUBYLIB path.
18
+ #
19
+ class Package
20
+
21
+ ##
22
+ # at first check the rospack's cache, if found use it.
23
+ # if not found, check all package path.
24
+ # @param [String] cache_file cache file of rospack
25
+ # @return [Array] fullpath list of all packages
26
+ def self.read_cache_or_find_all(cache_file="#{ENV['HOME']}/.ros/rospack_cache")
27
+ if File.exists?(cache_file)
28
+ f = File.open(cache_file)
29
+ root_line = f.gets.chop
30
+ package_path_line = f.gets.chop
31
+ if root_line == "#ROS_ROOT=#{ENV['ROS_ROOT']}" and
32
+ package_path_line == "#ROS_PACKAGE_PATH=#{ENV['ROS_PACKAGE_PATH']}"
33
+ packages = {}
34
+ while line = f.gets
35
+ packages[File.basename(line.chop)] = line.chop
36
+ end
37
+ packages
38
+ else
39
+ self.find_all_packages
40
+ end
41
+ else
42
+ self.find_all_packages
43
+ end
44
+ end
45
+
46
+ ##
47
+ # search all packages that has manifest.xml
48
+ # @param [Hash] packages current found packages
49
+ # @param [Array] roots root directories for searching
50
+ # @return [Array] fullpath list of all packages
51
+ def self.find_all_packages(packages={}, roots=ENV['ROS_PACKAGE_PATH'].split(':').push(ENV['ROS_ROOT']))
52
+ roots.each do |root|
53
+ if File.exists?("#{root}/manifest.xml")
54
+ packages[File.basename(root)] = root
55
+ else
56
+ if File.exists?(root)
57
+ Dir.foreach(root) do |path|
58
+ if path != "." and path != ".."
59
+ full_path = "#{root}/#{path}"
60
+ if File.directory?(full_path)
61
+ self.find_all_packages(packages, [full_path])
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
68
+ packages
69
+ end
70
+
71
+ ##
72
+ # all package path hash
73
+ #
74
+ @@all_packages = self.read_cache_or_find_all
75
+
76
+
77
+ ##
78
+ # get the depend packages of the arg
79
+ # @param [String] package find depends packages of this package
80
+ # @param [Array] packages current found depends
81
+ # @return [Array] packages
82
+ def self.depends(package, packages=[])
83
+ file = File.open("#{@@all_packages[package]}/manifest.xml")
84
+ doc = REXML::Document.new(file)
85
+ doc.elements.each('/package/depend') do |element|
86
+ depend_package = element.attributes['package']
87
+ if not packages.include?(depend_package)
88
+ packages.push(depend_package)
89
+ self.depends(depend_package, packages)
90
+ end
91
+ end
92
+ packages
93
+ end
94
+
95
+
96
+ ##
97
+ # get the current program's package
98
+ # @return [String] name of running programs's package
99
+ def self.find_this_package
100
+ path = File::dirname(File.expand_path($PROGRAM_NAME))
101
+ while path != '/'
102
+ if File.exists?("#{path}/manifest.xml")
103
+ return File::basename(path)
104
+ end
105
+ path = File::dirname(path)
106
+ end
107
+ nil
108
+ end
109
+
110
+ ##
111
+ # add package's [lib/, msg_gen/ruby, srv_gen/ruby] to '$:'.
112
+ # this enables load ruby files easily
113
+ # @param [String] package name of package
114
+ def self.add_path_of_package(package)
115
+ path = @@all_packages[package]
116
+ ["#{path}/msg_gen/ruby", "#{path}/srv_gen/ruby", "#{path}/lib"].each do |path|
117
+ if File.exists?(path)
118
+ if not $:.include?(path)
119
+ $:.push(path)
120
+ end
121
+ end
122
+ end
123
+ end
124
+
125
+ ##
126
+ # add [lib/, msg_gen/ruby, srv_gen/ruby] dirs of all depend packages
127
+ # to RUBYLIB, if the directory exists
128
+ # @param [String] package name of package
129
+ def self.add_path_with_depend_packages(package)
130
+ add_path_of_package(package)
131
+ Package::depends(package).each do |pack|
132
+ add_path_of_package(pack)
133
+ end
134
+ end
135
+
136
+ end
137
+
138
+ ##
139
+ # load manifest and add all dependencies
140
+ # @param [String] package name of package
141
+ def self.load_manifest(package)
142
+ ROS::Package.add_path_with_depend_packages(package)
143
+ end
144
+ end
@@ -0,0 +1,127 @@
1
+ # ros/parameter_manager.rb
2
+ #
3
+ # License: BSD
4
+ #
5
+ # Copyright (C) 2012 Takashi Ogura <t.ogura@gmail.com>
6
+ #
7
+ # == Control Parameter Server Interface
8
+ #
9
+ # ROS parameter sever inteface.
10
+ # API document is here http://ros.org/wiki/ROS/Parameter%20Server%20API
11
+ #
12
+ require "xmlrpc/client"
13
+
14
+ module ROS
15
+
16
+ # ROS parameter sever inteface.
17
+ # API document is here http://ros.org/wiki/ROS/Parameter%20Server%20API
18
+ class ParameterManager
19
+
20
+ # @param [String] master_uri URI of ROS Master (parameter server)
21
+ # @param [String] caller_id caller_id of this node
22
+ # @param [Array] remappings remapps to use for local remappings
23
+ def initialize(master_uri, caller_id, remappings)
24
+ @caller_id = caller_id
25
+ @master_uri = master_uri
26
+ @remappings = remappings
27
+ @server = XMLRPC::Client.new2(@master_uri)
28
+ end
29
+
30
+ ##
31
+ # get parameter named 'key'
32
+ # @param [String] key name of parameter
33
+ # @return [String] parameter value
34
+ def get_param(key)
35
+ if @remappings[key]
36
+ return @remappings[key]
37
+ end
38
+ code, message, value = @server.call("getParam", @caller_id, key)
39
+ case code
40
+ when 1
41
+ return value
42
+ else
43
+ return nil
44
+ end
45
+ end
46
+
47
+ ##
48
+ # set parameter for 'key'
49
+ # @param [String] key key of parameter
50
+ # @param [String, Integer, Float, Boolean] value value of parameter
51
+ # @return [Boolean] true if succeed
52
+ # @raise
53
+ def set_param(key, value)
54
+ code, message, value = @server.call("setParam", @caller_id, key, value)
55
+ case code
56
+ when 1
57
+ return true
58
+ when -1
59
+ raise message
60
+ else
61
+ return false
62
+ end
63
+ end
64
+
65
+ ##
66
+ # delete parameter 'key'
67
+ # @param [String] key key for remove
68
+ # @return [Boolean] return true if success, false if it is not exist
69
+ def delete_param(key)
70
+ code, message, value = @server.call("deleteParam", @caller_id, key)
71
+ case code
72
+ when 1
73
+ return true
74
+ else
75
+ return false
76
+ end
77
+ end
78
+
79
+ ##
80
+ # search the all namespace for key
81
+ # @param [String] key key for search
82
+ # @return [Array] values
83
+ def search_param(key)
84
+ code, message, value = @server.call("searchParam", @caller_id, key)
85
+ case code
86
+ when 1
87
+ return value
88
+ when -1
89
+ raise message
90
+ else
91
+ return false
92
+ end
93
+ end
94
+
95
+ ##
96
+ # check if the master has the key
97
+ # @param [String] key key for check
98
+ # @return [String, Integer, Float, Boolean] value of key
99
+ def has_param(key)
100
+ code, message, value = @server.call("hasParam", @caller_id, key)
101
+ case code
102
+ when 1
103
+ return value
104
+ when -1
105
+ raise message
106
+ else
107
+ return false
108
+ end
109
+ end
110
+
111
+ ##
112
+ # get the all keys of parameters
113
+ # @return [Array] all keys
114
+ #
115
+ def get_param_names
116
+ code, message, value = @server.call("getParamNames", @caller_id)
117
+ case code
118
+ when 1
119
+ return value
120
+ when -1
121
+ raise message
122
+ else
123
+ return false
124
+ end
125
+ end
126
+ end
127
+ end
@@ -0,0 +1,47 @@
1
+ # ros/parameter_subscriber.rb
2
+ #
3
+ # License: BSD
4
+ #
5
+ # Copyright (C) 2012 Takashi Ogura <t.ogura@gmail.com>
6
+ #
7
+ #
8
+ # == Parameter Subscriber
9
+ # callback object for paramUpdate
10
+ #
11
+ #
12
+
13
+ module ROS
14
+
15
+ # callback object for paramUpdate
16
+ #
17
+ class ParameterSubscriber
18
+ # do not make instance directory. Plese use Node#subscribe_parameter.
19
+ # @param [String] key param key to subscribe
20
+ # @param [Proc] callback callback when parameter updated
21
+ def initialize(key, callback)
22
+ @key = key
23
+ @callback = callback
24
+ end
25
+
26
+ # callback with param value
27
+ # @param [String] value value of updated parameter
28
+ def call(value)
29
+ @callback.call(value)
30
+ end
31
+
32
+ # set GraphManager for management
33
+ # @param [GraphManager] manager GraphManager
34
+ def set_manager(manager) #:nodoc
35
+ @manager = manager
36
+ end
37
+
38
+ # shutdown this subscription
39
+ def shutdown
40
+ @manager.shutdown_parameter_subscriber(self)
41
+ end
42
+
43
+ # key of parameter for subscription
44
+ attr_accessor :key
45
+
46
+ end
47
+ end
@@ -0,0 +1,96 @@
1
+ # ros/publisher.rb
2
+ #
3
+ # License: BSD
4
+ #
5
+ # Copyright (C) 2012 Takashi Ogura <t.ogura@gmail.com>
6
+ #
7
+
8
+ require 'ros/topic'
9
+ require 'ros/tcpros/server'
10
+
11
+ module ROS
12
+ # Publisher interface of ROS.
13
+ # A publisher contains multi connection with subscribers.
14
+ # TCPROS protocol implementation is in ROS::TCPROS::Server.
15
+ # Here is sample code. You can shutdown publisher by using this
16
+ # instance (ROS::Publisher#shutdown)
17
+ # node = ROS::Node.new('/rosruby/sample_publisher')
18
+ # publisher = node.advertise('/chatter', Std_msgs::String)
19
+ # sleep(1)
20
+ # msg = Std_msgs::String.new
21
+ # i = 0
22
+ # while node.ok?
23
+ # msg.data = "Hello, rosruby!: #{i}"
24
+ # publisher.publish(msg)
25
+ # i += 1
26
+ # end
27
+ class Publisher < Topic
28
+
29
+ # @param [String] caller_id caller_id of this node
30
+ # @param [String] topic_name name of topic to publish (String)
31
+ # @param [Class] topic_type class of topic
32
+ # @param [Boolean] is_latched latched topic?
33
+ # @param [String] host host name of this node
34
+ def initialize(caller_id, topic_name, topic_type, is_latched, host)
35
+ super(caller_id, topic_name, topic_type)
36
+ @host = host
37
+ @is_latched = is_latched
38
+ @seq = 0
39
+ end
40
+
41
+ ##
42
+ # publish msg object
43
+ # @param [Class] message instance of topic_type class
44
+ # @return [Publisher] self
45
+ def publish(message)
46
+ @seq += 1
47
+ @last_published_msg = message
48
+ if message.has_header?
49
+ message.header.seq = @seq
50
+ end
51
+ @connections.each do |connection|
52
+ connection.msg_queue.push(message)
53
+ end
54
+ self
55
+ end
56
+
57
+ ##
58
+ # add tcpros connection as server
59
+ # @param [String] caller_id caller_id of subscriber
60
+ # @return [TCPROS::Server] connection object
61
+ def add_connection(caller_id) #:nodoc:
62
+ connection = TCPROS::Server.new(@caller_id, @topic_name, @topic_type,
63
+ :host=>@host,
64
+ :latched=>@is_latched,
65
+ :last_published_msg=>@last_published_msg)
66
+ connection.start
67
+ connection.id = "#{@topic_name}_out_#{@connection_id_number}"
68
+ @connection_id_number += 1
69
+ @connections.push(connection)
70
+ return connection
71
+ end
72
+
73
+ # @return [Array] connection data for slave api
74
+ def get_connection_data
75
+ @connections.map do |connection|
76
+ [connection.id, connection.byte_sent, connection.num_sent, 1]
77
+ end
78
+ end
79
+
80
+ # @return [array] connection info for slave api
81
+ def get_connection_info
82
+ info = []
83
+ @connections.each do |connection|
84
+ info.push([connection.id, connection.caller_id, 'o', connection.protocol, @topic_name])
85
+ end
86
+ info
87
+ end
88
+
89
+ ##
90
+ # user interface of shutdown this publisher
91
+ # @return [nil] nil
92
+ def shutdown
93
+ @manager.shutdown_publisher(self)
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,41 @@
1
+ # ros/rate.rb
2
+ #
3
+ # License: BSD
4
+ #
5
+ # Copyright (C) 2012 Takashi Ogura <t.ogura@gmail.com>
6
+ #
7
+ #
8
+
9
+ module ROS
10
+
11
+ ##
12
+ # sleep in a Hz timing.
13
+ # @example
14
+ # r = ROS::Rate.new(10)
15
+ # r.sleep
16
+ #
17
+ class Rate
18
+
19
+ # @param [Float] hz Hz
20
+ def initialize(hz)
21
+ @sleep_duration = 1.0 / hz
22
+ @last_time = ::Time.now
23
+ end
24
+
25
+ ##
26
+ # sleep for preset rate [Hz]
27
+ #
28
+ def sleep
29
+ current_time = ::Time.now
30
+ elapsed = current_time - @last_time
31
+ Kernel.sleep(@sleep_duration - elapsed)
32
+ @last_time = @last_time + @sleep_duration
33
+
34
+ # detect time jumping forwards, as well as loops that are
35
+ # inherently too slow
36
+ if current_time - @last_time > @sleep_duration * 2
37
+ @last_time = current_time
38
+ end
39
+ end
40
+ end
41
+ end