Peeja-rubot 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
}
|