Peeja-rubot 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.autotest +4 -0
- data/Adapters.txt +3 -0
- data/History.txt +4 -0
- data/Manifest.txt +47 -0
- data/README.txt +53 -0
- data/Rakefile +31 -0
- data/bin/rubot +20 -0
- data/examples/navigate.rbt +60 -0
- data/ext/rubot_aria/RAGenericAction.cpp +87 -0
- data/ext/rubot_aria/RAGenericAction.h +96 -0
- data/ext/rubot_aria/RARobotManager.cpp +73 -0
- data/ext/rubot_aria/RARobotManager.h +30 -0
- data/ext/rubot_aria/extconf.rb +9 -0
- data/ext/rubot_aria/rubot_aria.cpp +63 -0
- data/lib/rubot.rb +14 -0
- data/lib/rubot/adapters.rb +39 -0
- data/lib/rubot/adapters/aria.rb +5 -0
- data/lib/rubot/adapters/aria/action_desired.rb +18 -0
- data/lib/rubot/adapters/aria/robot.rb +30 -0
- data/lib/rubot/adapters/asimov.rb +2 -0
- data/lib/rubot/dsl.rb +161 -0
- data/lib/rubot/meta.rb +13 -0
- data/spec/load_paths.rb +9 -0
- data/spec/rubot/adapters/aria/robot_manager_spec.rb +12 -0
- data/spec/rubot/adapters/aria/robot_spec.rb +38 -0
- data/spec/rubot/adapters/aria_spec.rb +5 -0
- data/spec/rubot/adapters/spec_helper.rb +16 -0
- data/spec/rubot/dsl_spec.rb +22 -0
- data/spec/rubot_spec.rb +4 -0
- data/spec/spec.opts +3 -0
- data/spec/spec_helper.rb +19 -0
- data/tasks/ann.rake +76 -0
- data/tasks/annotations.rake +22 -0
- data/tasks/doc.rake +48 -0
- data/tasks/gem.rake +110 -0
- data/tasks/manifest.rake +49 -0
- data/tasks/post_load.rake +26 -0
- data/tasks/rubyforge.rake +57 -0
- data/tasks/setup.rb +227 -0
- data/tasks/spec.rake +54 -0
- data/tasks/svn.rake +44 -0
- data/tasks/test.rake +38 -0
- metadata +121 -0
data/.autotest
ADDED
data/Adapters.txt
ADDED
data/History.txt
ADDED
data/Manifest.txt
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
.autotest
|
2
|
+
Adapters.txt
|
3
|
+
History.txt
|
4
|
+
Manifest.txt
|
5
|
+
README.txt
|
6
|
+
Rakefile
|
7
|
+
bin/rubot
|
8
|
+
examples/navigate.rbt
|
9
|
+
ext/rubot_aria/Makefile
|
10
|
+
ext/rubot_aria/RAGenericAction.cpp
|
11
|
+
ext/rubot_aria/RAGenericAction.h
|
12
|
+
ext/rubot_aria/RAGenericAction.o
|
13
|
+
ext/rubot_aria/RARobotManager.cpp
|
14
|
+
ext/rubot_aria/RARobotManager.h
|
15
|
+
ext/rubot_aria/RARobotManager.o
|
16
|
+
ext/rubot_aria/extconf.rb
|
17
|
+
ext/rubot_aria/rubot_aria.cpp
|
18
|
+
ext/rubot_aria/rubot_aria.o
|
19
|
+
ext/rubot_aria/rubot_aria.so
|
20
|
+
lib/rubot.rb
|
21
|
+
lib/rubot/adapters.rb
|
22
|
+
lib/rubot/adapters/aria.rb
|
23
|
+
lib/rubot/adapters/aria/action_desired.rb
|
24
|
+
lib/rubot/adapters/aria/robot.rb
|
25
|
+
lib/rubot/adapters/asimov.rb
|
26
|
+
lib/rubot/dsl.rb
|
27
|
+
lib/rubot/meta.rb
|
28
|
+
spec/load_paths.rb
|
29
|
+
spec/rubot/adapters/aria/robot_manager_spec.rb
|
30
|
+
spec/rubot/adapters/aria/robot_spec.rb
|
31
|
+
spec/rubot/adapters/aria_spec.rb
|
32
|
+
spec/rubot/adapters/spec_helper.rb
|
33
|
+
spec/rubot/dsl_spec.rb
|
34
|
+
spec/rubot_spec.rb
|
35
|
+
spec/spec.opts
|
36
|
+
spec/spec_helper.rb
|
37
|
+
tasks/ann.rake
|
38
|
+
tasks/annotations.rake
|
39
|
+
tasks/doc.rake
|
40
|
+
tasks/gem.rake
|
41
|
+
tasks/manifest.rake
|
42
|
+
tasks/post_load.rake
|
43
|
+
tasks/rubyforge.rake
|
44
|
+
tasks/setup.rb
|
45
|
+
tasks/spec.rake
|
46
|
+
tasks/svn.rake
|
47
|
+
tasks/test.rake
|
data/README.txt
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
IMPORTANT:
|
2
|
+
This version of Rubot is incomplete and presented publicly for the sole purpose (currently) of discussion and testing. Many things are broken, many files are incomplete. Even this README needs a good deal of work.
|
3
|
+
|
4
|
+
=====
|
5
|
+
|
6
|
+
rubot
|
7
|
+
by Peter Jaros (Peeja) <peter.a.jaros@gmail.com>
|
8
|
+
http://rubot.org/ (pending)
|
9
|
+
|
10
|
+
== DESCRIPTION:
|
11
|
+
|
12
|
+
FIXME (describe your package)
|
13
|
+
|
14
|
+
== FEATURES/PROBLEMS:
|
15
|
+
|
16
|
+
* FIXME (list of features or problems)
|
17
|
+
|
18
|
+
== SYNOPSIS:
|
19
|
+
|
20
|
+
rubot mycode.rbt
|
21
|
+
|
22
|
+
== REQUIREMENTS:
|
23
|
+
|
24
|
+
* FIXME (list of requirements)
|
25
|
+
|
26
|
+
== INSTALL:
|
27
|
+
|
28
|
+
* FIXME (sudo gem install, anything else)
|
29
|
+
|
30
|
+
== LICENSE:
|
31
|
+
|
32
|
+
(The MIT License)
|
33
|
+
|
34
|
+
Copyright (c) 2008
|
35
|
+
|
36
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
37
|
+
a copy of this software and associated documentation files (the
|
38
|
+
'Software'), to deal in the Software without restriction, including
|
39
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
40
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
41
|
+
permit persons to whom the Software is furnished to do so, subject to
|
42
|
+
the following conditions:
|
43
|
+
|
44
|
+
The above copyright notice and this permission notice shall be
|
45
|
+
included in all copies or substantial portions of the Software.
|
46
|
+
|
47
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
48
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
49
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
50
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
51
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
52
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
53
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# Look in the tasks/setup.rb file for the various options that can be
|
2
|
+
# configured in this Rakefile. The .rake files in the tasks directory
|
3
|
+
# are where the options are used.
|
4
|
+
|
5
|
+
load 'tasks/setup.rb'
|
6
|
+
|
7
|
+
ensure_in_path 'lib'
|
8
|
+
require 'rubot'
|
9
|
+
|
10
|
+
task :default => 'spec:run'
|
11
|
+
|
12
|
+
PROJ.name = 'rubot'
|
13
|
+
PROJ.authors = 'Peter Jaros (Peeja)'
|
14
|
+
PROJ.email = 'peter.a.jaros@gmail.com'
|
15
|
+
PROJ.url = 'http://rubot.org/'
|
16
|
+
# PROJ.rubyforge_name = 'rubot'
|
17
|
+
PROJ.version = Rubot.version
|
18
|
+
|
19
|
+
PROJ.executables = ['rubot']
|
20
|
+
PROJ.dependencies << ['rice', '>= 1.0.1'] << ['facets', '>= 2.3.0']
|
21
|
+
|
22
|
+
PROJ.spec_opts += File.read('spec/spec.opts').split
|
23
|
+
PROJ.spec_opts << '-fs'
|
24
|
+
|
25
|
+
# Don't expect test coverage of any file with an absolute path.
|
26
|
+
PROJ.rcov_opts << '--exclude' << '^/' << '--exclude' << 'meta.rb$'
|
27
|
+
PROJ.rcov_threshold_exact = true
|
28
|
+
|
29
|
+
PROJ.exclude << '^\.git/' << '\.gitignore$' << '/\.DS_Store$' << '^\.DS_Store$' << '/\._' << '^\._' << 'mkmf.log'
|
30
|
+
|
31
|
+
# EOF
|
data/bin/rubot
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
# require 'main'
|
5
|
+
require 'rubot'
|
6
|
+
|
7
|
+
# Main do
|
8
|
+
# argument 'file' do
|
9
|
+
# required
|
10
|
+
# description 'Rubot file to run'
|
11
|
+
# end
|
12
|
+
#
|
13
|
+
# def run
|
14
|
+
# include Rubot::DSL
|
15
|
+
# load params['file']
|
16
|
+
# end
|
17
|
+
# end
|
18
|
+
|
19
|
+
include Rubot::DSL
|
20
|
+
load ARGV[0]
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# navigate.rbt
|
2
|
+
|
3
|
+
# Make a behavior to go forward, slowing when we approach an obstacle.
|
4
|
+
|
5
|
+
behavior :go => [:max_speed, :stop_distance] do
|
6
|
+
sensors :sonar
|
7
|
+
|
8
|
+
fire do
|
9
|
+
range = sonar.range(-70,70) - robot.radius
|
10
|
+
if range > stop_distance
|
11
|
+
speed = range * 0.3
|
12
|
+
speed = max_speed if (speed > max_speed)
|
13
|
+
desired.velocity = speed
|
14
|
+
else
|
15
|
+
desired.velocity = 0
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
|
21
|
+
# Make another behavior to turn us around objects we can avoid.
|
22
|
+
|
23
|
+
behavior :turn => [:turn_threshold, :turn_amount] do
|
24
|
+
sensors :sonar
|
25
|
+
|
26
|
+
fire do
|
27
|
+
# Get the left readings and right readings off of the sonar
|
28
|
+
left_range = sonar.range(0,100) - robot.radius
|
29
|
+
right_range = sonar.range(-100,0) - robot.radius
|
30
|
+
if left_range > turn_threshold && right_range > turn_threshold
|
31
|
+
# if neither left nor right range is within the turn threshold,
|
32
|
+
# reset the turning variable and don't turn
|
33
|
+
turn_direction = nil
|
34
|
+
desired.delta_heading = 0;
|
35
|
+
else
|
36
|
+
turn_direction ||= (left_range < right_range ? :left : :right)
|
37
|
+
desired.delta_heading = turn_amount * ( turn_direction == :left ? -1 : 1 )
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
# Set up a robot.
|
44
|
+
|
45
|
+
robot :fred do
|
46
|
+
adapter :aria
|
47
|
+
host 'localhost'
|
48
|
+
|
49
|
+
sensors :sonar
|
50
|
+
|
51
|
+
behaviors do
|
52
|
+
go :priority => 50, :max_speed => 240, :stop_distance => 300
|
53
|
+
turn :priority => 49, :turn_threshold => 400, :turn_amount => 10
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
# Run it.
|
59
|
+
|
60
|
+
run :fred
|
@@ -0,0 +1,87 @@
|
|
1
|
+
#include "rice/Object.hpp"
|
2
|
+
#include "rice/Data_Type.hpp"
|
3
|
+
#include "rice/Symbol.hpp"
|
4
|
+
#include "rice/Exception.hpp"
|
5
|
+
#include "Aria.h"
|
6
|
+
|
7
|
+
#include "RAGenericAction.h"
|
8
|
+
|
9
|
+
using namespace Rice;
|
10
|
+
|
11
|
+
RAGenericAction::RAGenericAction(const char *name)
|
12
|
+
: ArAction(name)
|
13
|
+
{
|
14
|
+
ArLog::log(ArLog::Normal, "Created generic action \"%s\".", name);
|
15
|
+
myFireProc = NULL;
|
16
|
+
myFireProc_guard = NULL;
|
17
|
+
|
18
|
+
// Sensors
|
19
|
+
mySonar = NULL;
|
20
|
+
}
|
21
|
+
|
22
|
+
RAGenericAction::~RAGenericAction()
|
23
|
+
{
|
24
|
+
if (myFireProc != NULL) {
|
25
|
+
delete myFireProc;
|
26
|
+
delete myFireProc_guard;
|
27
|
+
}
|
28
|
+
ArLog::log(ArLog::Normal, "Destroyed generic action \"%s\".", getName());
|
29
|
+
}
|
30
|
+
|
31
|
+
ArActionDesired *RAGenericAction::fire(ArActionDesired currentDesired)
|
32
|
+
{
|
33
|
+
myDesired.reset();
|
34
|
+
|
35
|
+
// FIXME: myFireProc eventually has type 0 (T_NONE), and calling #call segfaults.
|
36
|
+
// Only happens when multiple behaviors are used at once.
|
37
|
+
// if (myFireProc != NULL && myFireProc->rb_type() == 0)
|
38
|
+
// ArLog::log(ArLog::Normal, "Proc has type: %d.", myFireProc->rb_type());
|
39
|
+
|
40
|
+
if (myFireProc != NULL)
|
41
|
+
myFireProc->call("call");
|
42
|
+
|
43
|
+
return &myDesired;
|
44
|
+
}
|
45
|
+
|
46
|
+
void RAGenericAction::setFireProc(Object proc)
|
47
|
+
{
|
48
|
+
if (!proc.is_a(rb_cProc))
|
49
|
+
throw Exception(rb_eArgError, "proc needs to be a Proc.");
|
50
|
+
if (myFireProc != NULL) {
|
51
|
+
delete myFireProc;
|
52
|
+
delete myFireProc_guard;
|
53
|
+
}
|
54
|
+
myFireProc = new Object(proc);
|
55
|
+
myFireProc_guard = new Address_Registration_Guard(myFireProc);
|
56
|
+
}
|
57
|
+
|
58
|
+
void RAGenericAction::setSensors(Object sensors)
|
59
|
+
{
|
60
|
+
// TODO: Make sure rubot_aria supports the given sensors.
|
61
|
+
// ArLog::log(ArLog::Normal, "Action \"%s\"'s sensors started with \"%s\".", getName(), Symbol(mySensors.call("first")).c_str());
|
62
|
+
mySensors.call("replace", Array(sensors));
|
63
|
+
// ArLog::log(ArLog::Normal, "Action \"%s\"'s sensors now start with \"%s\".", getName(), Symbol(mySensors.call("first")).c_str());
|
64
|
+
}
|
65
|
+
|
66
|
+
void RAGenericAction::setRobot(ArRobot *robot)
|
67
|
+
{
|
68
|
+
ArAction::setRobot(robot);
|
69
|
+
ArLog::log(ArLog::Normal, "Setting robot for action \"%s\".", getName());
|
70
|
+
|
71
|
+
// Acquire sensors.
|
72
|
+
// TODO: Handle robot not supporting sensors better.
|
73
|
+
for (Array::iterator it = mySensors.begin(); it != mySensors.end(); ++it) {
|
74
|
+
if (*it == Symbol("sonar")) {
|
75
|
+
ArLog::log(ArLog::Normal, "Adding sonar.");
|
76
|
+
mySonar = robot->findRangeDevice("sonar");
|
77
|
+
}
|
78
|
+
}
|
79
|
+
}
|
80
|
+
|
81
|
+
Object RAGenericAction::getSensor(Symbol sensor)
|
82
|
+
{
|
83
|
+
if (sensor == Symbol("sonar") && mySonar)
|
84
|
+
return to_ruby(mySonar);
|
85
|
+
else
|
86
|
+
return Object(Qnil);
|
87
|
+
}
|
@@ -0,0 +1,96 @@
|
|
1
|
+
#pragma once
|
2
|
+
|
3
|
+
#include "rice/Array.hpp"
|
4
|
+
#include "rice/Object.hpp"
|
5
|
+
#include "rice/Data_Object.hpp"
|
6
|
+
#include "rice/Address_Registration_Guard.hpp"
|
7
|
+
#include "Aria.h"
|
8
|
+
|
9
|
+
/*
|
10
|
+
* RAGenericAction
|
11
|
+
* Generic ArAction that runs a Ruby proc when it fires.
|
12
|
+
*
|
13
|
+
*/
|
14
|
+
|
15
|
+
class RAGenericAction : public ArAction
|
16
|
+
{
|
17
|
+
public:
|
18
|
+
RAGenericAction(const char *name);
|
19
|
+
virtual ~RAGenericAction(void);
|
20
|
+
virtual ArActionDesired *fire(ArActionDesired currentDesired);
|
21
|
+
void setFireProc(Rice::Object proc);
|
22
|
+
void setSensors(Rice::Object sensors);
|
23
|
+
Rice::Object getSensor(Rice::Symbol sensor);
|
24
|
+
virtual void setRobot(ArRobot *robot);
|
25
|
+
ArActionDesired *getActionDesired() { return &myDesired; }
|
26
|
+
|
27
|
+
protected:
|
28
|
+
ArActionDesired myDesired;
|
29
|
+
Rice::Object *myFireProc;
|
30
|
+
Rice::Address_Registration_Guard *myFireProc_guard;
|
31
|
+
Rice::Array mySensors;
|
32
|
+
|
33
|
+
// Sensors
|
34
|
+
ArRangeDevice *mySonar;
|
35
|
+
};
|
36
|
+
|
37
|
+
|
38
|
+
// We need a disposable wrapper for ArActionDesired which Ruby can GC at its
|
39
|
+
// pleasure. This class delegates all calls to its wrapped ArActionDesired.
|
40
|
+
// We have to duplicate the entirety of the interface we want Ruby to be able
|
41
|
+
// to use. It would be nice to automate this somehow with macros.
|
42
|
+
|
43
|
+
class ArActionDesiredWrap
|
44
|
+
{
|
45
|
+
public:
|
46
|
+
ArActionDesiredWrap(ArActionDesired *obj) { myObj = obj; }
|
47
|
+
virtual ~ArActionDesiredWrap() {}
|
48
|
+
|
49
|
+
double getVel() const { return myObj->getVel(); }
|
50
|
+
double getVelStrength() const { return myObj->getVelStrength(); }
|
51
|
+
void setVel(double vel, double strength) const { myObj->setVel(vel, strength); }
|
52
|
+
|
53
|
+
double getDeltaHeading() const { return myObj->getDeltaHeading(); }
|
54
|
+
double getDeltaHeadingStrength() const { return myObj->getDeltaHeadingStrength(); }
|
55
|
+
void setDeltaHeading(double deltaHeading, double strength) const { myObj->setDeltaHeading(deltaHeading, strength); }
|
56
|
+
|
57
|
+
double getHeading() const { return myObj->getHeading(); }
|
58
|
+
double getHeadingStrength() const { return myObj->getHeadingStrength(); }
|
59
|
+
void setHeading(double heading, double strength) const { myObj->setHeading(heading, strength); }
|
60
|
+
|
61
|
+
private:
|
62
|
+
ArActionDesired *myObj;
|
63
|
+
};
|
64
|
+
|
65
|
+
template<>
|
66
|
+
inline
|
67
|
+
Rice::Object to_ruby<ArActionDesired *>(ArActionDesired * const & x)
|
68
|
+
{
|
69
|
+
return Rice::Data_Object<ArActionDesiredWrap>(new ArActionDesiredWrap(x));
|
70
|
+
}
|
71
|
+
|
72
|
+
|
73
|
+
// We also need a wrapper for ArRangeDevice.
|
74
|
+
|
75
|
+
class ArRangeDeviceWrap
|
76
|
+
{
|
77
|
+
public:
|
78
|
+
ArRangeDeviceWrap(ArRangeDevice *obj) { myObj = obj; }
|
79
|
+
virtual ~ArRangeDeviceWrap() { }
|
80
|
+
|
81
|
+
double currentReadingPolar(double startAngle, double endAngle)
|
82
|
+
{
|
83
|
+
return myObj->currentReadingPolar(startAngle, endAngle, NULL);
|
84
|
+
}
|
85
|
+
|
86
|
+
private:
|
87
|
+
ArRangeDevice *myObj;
|
88
|
+
};
|
89
|
+
|
90
|
+
|
91
|
+
template<>
|
92
|
+
inline
|
93
|
+
Rice::Object to_ruby<ArRangeDevice *>(ArRangeDevice * const & x)
|
94
|
+
{
|
95
|
+
return Rice::Data_Object<ArRangeDeviceWrap>(new ArRangeDeviceWrap(x));
|
96
|
+
}
|
@@ -0,0 +1,73 @@
|
|
1
|
+
#include "Aria.h"
|
2
|
+
#include "RARobotManager.h"
|
3
|
+
|
4
|
+
using namespace Rice;
|
5
|
+
|
6
|
+
|
7
|
+
RARobotManager::RARobotManager()
|
8
|
+
: myRobot(), myStopCB(this, &RARobotManager::stop)
|
9
|
+
{
|
10
|
+
ArLog::log(ArLog::Normal, "Created robot manager.");
|
11
|
+
myRobotKeyHandler = NULL;
|
12
|
+
|
13
|
+
// Sensors
|
14
|
+
mySonar = NULL;
|
15
|
+
}
|
16
|
+
|
17
|
+
RARobotManager::~RARobotManager()
|
18
|
+
{
|
19
|
+
if (myRobotKeyHandler != NULL)
|
20
|
+
delete myRobotKeyHandler;
|
21
|
+
if (mySonar != NULL)
|
22
|
+
delete mySonar;
|
23
|
+
ArLog::log(ArLog::Normal, "Destroyed robot manager.");
|
24
|
+
}
|
25
|
+
|
26
|
+
// Connect to robot and run.
|
27
|
+
void RARobotManager::go(const char *argString="")
|
28
|
+
{
|
29
|
+
ArArgumentBuilder args;
|
30
|
+
args.add(argString);
|
31
|
+
ArSimpleConnector conn(&args);
|
32
|
+
conn.parseArgs();
|
33
|
+
// TODO: Handle connection error
|
34
|
+
conn.connectRobot(&myRobot);
|
35
|
+
myRobot.enableMotors();
|
36
|
+
|
37
|
+
if (myRobotKeyHandler != NULL)
|
38
|
+
delete myRobotKeyHandler;
|
39
|
+
myRobotKeyHandler = new ArKeyHandler(false, false);
|
40
|
+
myRobotKeyHandler->addKeyHandler(ArKeyHandler::ESCAPE, &myStopCB);
|
41
|
+
myRobot.attachKeyHandler(myRobotKeyHandler, false);
|
42
|
+
|
43
|
+
myRobot.run(true);
|
44
|
+
}
|
45
|
+
|
46
|
+
|
47
|
+
void RARobotManager::stop()
|
48
|
+
{
|
49
|
+
myRobot.stopRunning();
|
50
|
+
if (myRobotKeyHandler != NULL) {
|
51
|
+
delete myRobotKeyHandler;
|
52
|
+
myRobotKeyHandler = NULL;
|
53
|
+
}
|
54
|
+
}
|
55
|
+
|
56
|
+
|
57
|
+
void RARobotManager::addAction(RAGenericAction *action, int priority)
|
58
|
+
{
|
59
|
+
ArLog::log(ArLog::Normal, "Adding action \"%s\" with priority %d.", action->getName(), priority);
|
60
|
+
myRobot.addAction(action, priority);
|
61
|
+
}
|
62
|
+
|
63
|
+
|
64
|
+
void RARobotManager::addSensor(Symbol sensor)
|
65
|
+
{
|
66
|
+
if (sensor == Symbol("sonar") && mySonar == NULL) {
|
67
|
+
mySonar = new ArSonarDevice;
|
68
|
+
myRobot.addRangeDevice(mySonar);
|
69
|
+
}
|
70
|
+
else {
|
71
|
+
// TODO: Tell user if sensor is not supported.
|
72
|
+
}
|
73
|
+
}
|