pangdudu-robots 0.2.0 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- data/funky-examples/memory-agent/memory_agent.rb +250 -0
- data/funky-examples/memory-agent/memory_generator_agent.rb +59 -0
- data/funky-examples/talking-swift-agent/README +14 -0
- data/funky-examples/talking-swift-agent/talking_swift_agent.rb +44 -0
- data/funky-examples/talking-swift-agent/text_generator.rb +38 -0
- metadata +7 -2
@@ -0,0 +1,250 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'dm-core' #sudo gem install datamapper
|
3
|
+
require 'do_mysql' #sudo gem install do_mysql
|
4
|
+
require 'dm-timestamps' #sudo gem install dm-timestamps
|
5
|
+
require 'rofl' #sudo gem install pangdudu-rofl --source=http://gems.github.com
|
6
|
+
require 'robots' #sudo gem install pangdudu-robots --source=http://gems.github.com
|
7
|
+
require 'robots_xml'
|
8
|
+
|
9
|
+
#the RobotsXml module supplies nice methods for xml handling
|
10
|
+
#create xml messages like this: xml_msg = create_xml_msg { |b| b.body("test"); b.info("timestamp" => "#{Time.now}") }
|
11
|
+
#send them like this: send_msg xml_msg
|
12
|
+
#parse them like this: parse_xml_msg xml_msg,xpath
|
13
|
+
|
14
|
+
#do the mysql datamapper setup
|
15
|
+
DataMapper.setup(:default,{:adapter => 'mysql',:host => 'localhost',:username => 'robots',:password => 'robots!secret',:database => 'robots'})
|
16
|
+
|
17
|
+
#if you don't want to use a mysql database, or just need raw speed, check this out
|
18
|
+
#DataMapper.setup(:in_memory, :adapter => 'in_memory')
|
19
|
+
|
20
|
+
#and define a memory class
|
21
|
+
class Memory
|
22
|
+
include DataMapper::Resource
|
23
|
+
property :index, Serial
|
24
|
+
property :value, Text
|
25
|
+
property :created_at, DateTime
|
26
|
+
property :created_on, Date
|
27
|
+
property :updated_at, DateTime
|
28
|
+
property :updated_on, Date
|
29
|
+
#property :deleted_at, ParanoidDateTime
|
30
|
+
has n, :questions, :through => Resource
|
31
|
+
has n, :keywords, :through => Resource
|
32
|
+
end
|
33
|
+
|
34
|
+
#and define a memory class
|
35
|
+
class Question
|
36
|
+
include DataMapper::Resource
|
37
|
+
property :index, Serial
|
38
|
+
property :value, Text
|
39
|
+
property :created_at, DateTime
|
40
|
+
property :created_on, Date
|
41
|
+
property :updated_at, DateTime
|
42
|
+
property :updated_on, Date
|
43
|
+
#property :deleted_at, ParanoidDateTime
|
44
|
+
has n, :memories, :through => Resource
|
45
|
+
end
|
46
|
+
|
47
|
+
#memories may have keywords
|
48
|
+
class Keyword
|
49
|
+
include DataMapper::Resource
|
50
|
+
property :index, Serial
|
51
|
+
property :value, String
|
52
|
+
property :created_at, DateTime
|
53
|
+
property :created_on, Date
|
54
|
+
property :updated_at, DateTime
|
55
|
+
property :updated_on, Date
|
56
|
+
#property :deleted_at, ParanoidDateTime
|
57
|
+
has n, :memories, :through => Resource
|
58
|
+
end
|
59
|
+
|
60
|
+
#if your records aren't persistent, try removing the migrate statements
|
61
|
+
DataMapper.auto_migrate!
|
62
|
+
#Memory.auto_migrate!
|
63
|
+
#Question.auto_migrate!
|
64
|
+
#Keyword.auto_migrate!
|
65
|
+
|
66
|
+
class MemoryAgent
|
67
|
+
include Robots
|
68
|
+
include RobotsXml
|
69
|
+
|
70
|
+
def initialize
|
71
|
+
ilog "RobotsProto initialized"
|
72
|
+
end
|
73
|
+
|
74
|
+
#process an incoming memory message
|
75
|
+
def process_memory_msg xml_msg
|
76
|
+
memories = get_memories xml_msg
|
77
|
+
questions = get_questions xml_msg
|
78
|
+
keywords = get_keywords xml_msg
|
79
|
+
#remember a memory
|
80
|
+
#rather check for Array class here, lazy...
|
81
|
+
unless (memories.eql? "question") || (memories.eql? "keywords") || (memories.eql? "memories")
|
82
|
+
memories.each {|m| process_memory m,questions,keywords}
|
83
|
+
end
|
84
|
+
#ask a question and return memories
|
85
|
+
if memories.eql? "question"
|
86
|
+
questions.each {|q| process_question q}
|
87
|
+
end
|
88
|
+
#retrieve memories for keywords
|
89
|
+
if memories.eql? "memories"
|
90
|
+
process_keywords keywords
|
91
|
+
end
|
92
|
+
#retrieve keywords for a memory
|
93
|
+
#if memories.eql? "keywords"
|
94
|
+
#end
|
95
|
+
end
|
96
|
+
|
97
|
+
#process a single memory
|
98
|
+
def process_memory memory,questions,keywords
|
99
|
+
questions.each {|q| memory.questions << q}
|
100
|
+
keywords.each {|k| memory.keywords << k}
|
101
|
+
#finally save the updated memory to the storage
|
102
|
+
memory.save
|
103
|
+
end
|
104
|
+
|
105
|
+
#process a question
|
106
|
+
def process_question question
|
107
|
+
qval = question.value
|
108
|
+
#get all question with that value from storage
|
109
|
+
questions = Question.all(:value => qval)
|
110
|
+
memories = {} #single values behind key, so only newest memory will be returned
|
111
|
+
#get all associated memories from storage
|
112
|
+
questions.each { |q| q.memories.each { |m| memories[m.value] = m } }
|
113
|
+
memories.each do |n,m|
|
114
|
+
#create a response message
|
115
|
+
msg = create_xml_msg { |b| b.memory_response(m.value,"action"=>"question-response","question"=>qval,"timestamp" => "#{Time.now}") }
|
116
|
+
#send response message to system
|
117
|
+
send_msg msg
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
#process keywords, and return matching memories to system
|
122
|
+
def process_keywords keywords
|
123
|
+
memories = {}
|
124
|
+
keys = []
|
125
|
+
#the following could be a super nasty oneliner :)
|
126
|
+
keywords.each do |keyword|
|
127
|
+
keys << keyword.value #use that later for sorting
|
128
|
+
(Keyword.all(:value => keyword.value)).each do |k|
|
129
|
+
k.memories.each do |m|
|
130
|
+
if memories.has_key? m.value
|
131
|
+
memories[m.value][k.value] = "key" #add another keyword
|
132
|
+
else
|
133
|
+
memories[m.value] = {k.value => "key"} #it's a new entry
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
#oki, we now know which memories have what keywords, now we sort out the good ones
|
139
|
+
cinderella = {}
|
140
|
+
memories.each do |value,keywords|
|
141
|
+
good = true
|
142
|
+
keys.each { |key| good = false unless keywords.has_key? key }
|
143
|
+
#send message if we're good
|
144
|
+
if good
|
145
|
+
keys_string = ""
|
146
|
+
keys.each { |k| keys_string += "#{k} " }
|
147
|
+
msg = create_xml_msg { |b| b.memory_response(value,"action"=>"keywords-response","keywords"=>keys_string,"timestamp" => "#{Time.now}") }
|
148
|
+
end
|
149
|
+
end
|
150
|
+
#ok, there probably would have been a more datamapperish way to do this, tell me if you know one :)
|
151
|
+
#dlog cinderella.inspect
|
152
|
+
end
|
153
|
+
|
154
|
+
#get the memories from an xml_msg
|
155
|
+
def get_memories xml_msg
|
156
|
+
memories = []
|
157
|
+
mems = parse_xml_msg xml_msg,"//memory"
|
158
|
+
mems.each do |m|
|
159
|
+
if m.attributes["action"].eql? "remember"
|
160
|
+
memory = Memory.new(:value => m.inner_text)
|
161
|
+
memory.save
|
162
|
+
memories << memory
|
163
|
+
end
|
164
|
+
return "question" if m.attributes["action"].eql? "question" #ask a question, retrieve memory
|
165
|
+
return "keywords" if m.attributes["action"].eql? "keywords" #retrieve keywords for memory - not implemented yet
|
166
|
+
return "memories" if m.attributes["action"].eql? "memories" #retrieve memories for keywords
|
167
|
+
end
|
168
|
+
return memories
|
169
|
+
end
|
170
|
+
|
171
|
+
#get the keywords from an xml_msg
|
172
|
+
def get_keywords xml_msg
|
173
|
+
keywords = []
|
174
|
+
keys = parse_xml_msg xml_msg,"//keyword"
|
175
|
+
keys.each do |k|
|
176
|
+
keyword = Keyword.new(:value => k.inner_text)
|
177
|
+
keyword.save
|
178
|
+
keywords << keyword
|
179
|
+
end
|
180
|
+
return keywords
|
181
|
+
end
|
182
|
+
|
183
|
+
#get the questions from an xml_msg
|
184
|
+
def get_questions xml_msg
|
185
|
+
questions = []
|
186
|
+
quests = parse_xml_msg xml_msg,"//question"
|
187
|
+
quests.each do |q|
|
188
|
+
question = Question.new(:value => q.inner_text)
|
189
|
+
questions << question
|
190
|
+
question.save if q.attributes["action"].eql? "remember"
|
191
|
+
end
|
192
|
+
return questions
|
193
|
+
end
|
194
|
+
|
195
|
+
#ROBOTS message parsing stuff
|
196
|
+
|
197
|
+
#method that gets called when a new message arrives
|
198
|
+
def receive_msg msg
|
199
|
+
check_for_interests msg
|
200
|
+
end
|
201
|
+
|
202
|
+
#check if this msg interests us
|
203
|
+
def check_for_interests xml_msg
|
204
|
+
#message filter callback looks like this now
|
205
|
+
memory = parse_xml_msg xml_msg,"//memory"
|
206
|
+
process_memory_msg xml_msg unless memory.empty?
|
207
|
+
end
|
208
|
+
=begin
|
209
|
+
memory messages:
|
210
|
+
|
211
|
+
remember a memory:
|
212
|
+
<msg>
|
213
|
+
<memory action="remember">something happened</memory>
|
214
|
+
<question action="remember">what happened?</question>
|
215
|
+
<keyword>stuff</keyword>
|
216
|
+
<keyword>happening</keyword>
|
217
|
+
</msg>
|
218
|
+
|
219
|
+
ask a question:
|
220
|
+
<msg>
|
221
|
+
<memory action="question"></memory>
|
222
|
+
<question action="ask">what happened?</question>
|
223
|
+
</msg>
|
224
|
+
|
225
|
+
retrieve memories matching keywords:
|
226
|
+
<msg>
|
227
|
+
<memory action="memories"></memory>
|
228
|
+
<keyword>stuff</keyword>
|
229
|
+
<keyword>happening</keyword>
|
230
|
+
</msg>
|
231
|
+
|
232
|
+
not yet implemented, to lazy, retrieve keywords:
|
233
|
+
<msg>
|
234
|
+
<memory action="keywords">something happened</memory>
|
235
|
+
</msg>
|
236
|
+
=end
|
237
|
+
end
|
238
|
+
|
239
|
+
#start the app
|
240
|
+
ma = MemoryAgent.new
|
241
|
+
#=begin
|
242
|
+
ma.release_robots #start the robot agent module
|
243
|
+
|
244
|
+
#build you own loop if you need one
|
245
|
+
loop do
|
246
|
+
sleep 1
|
247
|
+
#send an xml message over the system
|
248
|
+
ma.send_msg ma.create_xml_msg { |b| b.info("memory agent alive","timestamp" => "#{Time.now}") }
|
249
|
+
end
|
250
|
+
#=end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rofl' #sudo gem install pangdudu-rofl --source=http://gems.github.com
|
3
|
+
require 'robots' #sudo gem install pangdudu-robots --source=http://gems.github.com
|
4
|
+
require 'robots_xml'
|
5
|
+
|
6
|
+
#the RobotsXml module supplies nice methods for xml handling
|
7
|
+
#create xml messages like this: xml_msg = create_xml_msg { |b| b.body("test"); b.info("timestamp" => "#{Time.now}") }
|
8
|
+
#send them like this: send_msg xml_msg
|
9
|
+
#parse them like this: parse_xml_msg xml_msg,xpath
|
10
|
+
|
11
|
+
class MemoryGeneratorAgent
|
12
|
+
include Robots
|
13
|
+
include RobotsXml
|
14
|
+
|
15
|
+
def initialize
|
16
|
+
ilog "MemoryGeneratorAgent initialized"
|
17
|
+
end
|
18
|
+
|
19
|
+
#ROBOTS message parsing stuff
|
20
|
+
|
21
|
+
#method that gets called when a new message arrives
|
22
|
+
def receive_msg msg
|
23
|
+
check_for_interests msg
|
24
|
+
end
|
25
|
+
|
26
|
+
#check if this msg interests us
|
27
|
+
def check_for_interests xml_msg
|
28
|
+
#message filter callback looks like this now
|
29
|
+
memory = parse_xml_msg xml_msg,"//memory"
|
30
|
+
dlog memory unless memory.empty?
|
31
|
+
#message filter callback looks like this now
|
32
|
+
info = parse_xml_msg xml_msg,"//info"
|
33
|
+
dlog info unless info.empty?
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
#start the app
|
39
|
+
mga = MemoryGeneratorAgent.new
|
40
|
+
#begin
|
41
|
+
|
42
|
+
mga.release_robots #start the robot agent module
|
43
|
+
|
44
|
+
#build you own loop if you need one
|
45
|
+
loop do
|
46
|
+
sleep 3
|
47
|
+
#send an xml message over the system
|
48
|
+
mga.send_msg mga.create_xml_msg { |b| b.info("memory generator agent alive","timestamp" => "#{Time.now}") }
|
49
|
+
#generate some bogus memory remember
|
50
|
+
mga.send_msg mga.create_xml_msg { |b| b.memory("something happened","action" => "remember");b.question("what happened?","action"=>"remember");b.keyword("stuff");b.keyword("happening") }
|
51
|
+
#generate bogus ask question
|
52
|
+
mga.send_msg mga.create_xml_msg { |b| b.memory("action" => "question");b.question("what happened?","action"=>"ask") }
|
53
|
+
#generate bogus retrieve keywords
|
54
|
+
mga.send_msg mga.create_xml_msg { |b| b.memory("something happened","action" => "keywords");}
|
55
|
+
#generate bogus retrieve memories from keywords
|
56
|
+
mga.send_msg mga.create_xml_msg { |b| b.memory("action" => "memories");b.keyword("stuff");b.keyword("happening") }
|
57
|
+
end
|
58
|
+
|
59
|
+
#end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
Hello!
|
2
|
+
|
3
|
+
in order to use swift, you need a cepstral swift voice: http://cepstral.com/downloads/
|
4
|
+
|
5
|
+
they are industry standard unit selection voices, and come with an api, i think it's
|
6
|
+
worth the bugs.
|
7
|
+
|
8
|
+
if you have a voice checkout and build: http://github.com/pangdudu/swiftly/tree/master
|
9
|
+
|
10
|
+
FREE ALTERNATIVE:
|
11
|
+
|
12
|
+
a free alternative that is easy to use, would be libflite: sudo gem install flite4r
|
13
|
+
|
14
|
+
have fun.
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'swiftly' #have a look at: http://github.com/pangdudu/swiftly/tree/master
|
3
|
+
require 'rofl' #sudo gem install pangdudu-rofl --source=http://gems.github.com
|
4
|
+
require 'robots' #sudo gem install pangdudu-robots --source=http://gems.github.com
|
5
|
+
require 'robots_xml'
|
6
|
+
|
7
|
+
#the RobotsXml module supplies nice methods for xml handling
|
8
|
+
#create xml messages like this: xml_msg = create_xml_msg { |b| b.body("test"); b.info("timestamp" => "#{Time.now}") }
|
9
|
+
#send them like this: send_msg xml_msg
|
10
|
+
#parse them like this: parse_xml_msg xml_msg,xpath
|
11
|
+
|
12
|
+
class SwiftAgent
|
13
|
+
include Swiftly
|
14
|
+
include Robots
|
15
|
+
include RobotsXml
|
16
|
+
|
17
|
+
def initialize
|
18
|
+
ilog "SwiftAgent initialized"
|
19
|
+
end
|
20
|
+
|
21
|
+
#method that gets called when a new message arrives
|
22
|
+
def receive_msg msg
|
23
|
+
check_for_interests msg
|
24
|
+
end
|
25
|
+
|
26
|
+
#check if this msg interests us
|
27
|
+
def check_for_interests xml_msg
|
28
|
+
#message filter callback looks like this now
|
29
|
+
text = parse_xml_msg xml_msg,"//speak"
|
30
|
+
speak text.inner_text unless text.empty?
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
#start the app
|
36
|
+
sa = SwiftAgent.new
|
37
|
+
sa.release_robots #start the robot agent module
|
38
|
+
|
39
|
+
#build you own loop if you need one
|
40
|
+
loop do
|
41
|
+
sleep 1
|
42
|
+
#send an xml message over the system
|
43
|
+
sa.send_msg sa.create_xml_msg { |b| b.body("swift alive"); b.info("timestamp" => "#{Time.now}") }
|
44
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rofl' #sudo gem install pangdudu-rofl --source=http://gems.github.com
|
3
|
+
require 'robots' #sudo gem install pangdudu-robots --source=http://gems.github.com
|
4
|
+
require 'robots_xml'
|
5
|
+
|
6
|
+
#the RobotsXml module supplies nice methods for xml handling
|
7
|
+
#create xml messages like this: xml_msg = create_xml_msg { |b| b.body("test"); b.info("timestamp" => "#{Time.now}") }
|
8
|
+
#send them like this: send_msg xml_msg
|
9
|
+
#parse them like this: parse_xml_msg xml_msg,xpath
|
10
|
+
|
11
|
+
class TextGenerator
|
12
|
+
include Robots
|
13
|
+
include RobotsXml
|
14
|
+
|
15
|
+
def initialize
|
16
|
+
ilog "TextGenerator initialized"
|
17
|
+
end
|
18
|
+
|
19
|
+
#method that gets called when a new message arrives
|
20
|
+
def receive_msg msg
|
21
|
+
end
|
22
|
+
|
23
|
+
#check if this msg interests us
|
24
|
+
def check_for_interests xml_msg
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
#start the app
|
30
|
+
tg = TextGenerator.new
|
31
|
+
tg.release_robots #start the robot agent module
|
32
|
+
|
33
|
+
#build you own loop if you need one
|
34
|
+
loop do
|
35
|
+
sleep 5
|
36
|
+
#send an xml message over the system
|
37
|
+
tg.send_msg tg.create_xml_msg { |b| b.speak("the robots say hello!"); b.info("timestamp" => "#{Time.now}") }
|
38
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pangdudu-robots
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- pangdudu
|
@@ -13,7 +13,7 @@ date: 2009-07-17 00:00:00 -07:00
|
|
13
13
|
default_executable: robots
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
|
-
name: dbus
|
16
|
+
name: pangdudu-ruby-dbus
|
17
17
|
type: :runtime
|
18
18
|
version_requirement:
|
19
19
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -39,6 +39,11 @@ files:
|
|
39
39
|
- lib/robots_xml.rb
|
40
40
|
- lib/robots_prototype.rb
|
41
41
|
- config/org.robots.service.conf
|
42
|
+
- funky-examples/talking-swift-agent/README
|
43
|
+
- funky-examples/talking-swift-agent/talking_swift_agent.rb
|
44
|
+
- funky-examples/talking-swift-agent/text_generator.rb
|
45
|
+
- funky-examples/memory-agent/memory_agent.rb
|
46
|
+
- funky-examples/memory-agent/memory_generator_agent.rb
|
42
47
|
has_rdoc: true
|
43
48
|
homepage: http://github.com/pangdudu/robots
|
44
49
|
post_install_message:
|