Plug-in structure
m (→Method implementation) |
(→Global variables and inter-plug-in calls) |
||
(One intermediate revision by one user not shown) | |||
Line 177: | Line 177: | ||
== Global variables and inter-plug-in calls == | == Global variables and inter-plug-in calls == | ||
− | See | + | See [[Variables]]. |
+ | |||
+ | The inter-plug-in calls has an alternative implementation that takes UVariable as parameter (for both strings, doubles and arrays) this makes calls simpler in some cases. | ||
+ | |||
+ | @todo describe the call implementation using UVariable parameters. | ||
== Laser scanner access == | == Laser scanner access == |
Latest revision as of 15:17, 25 April 2010
Contents |
[edit] Introduction
A plug-in is a library module that be loaded by an AURS server and extend the functionality of the server. The plug-in can use the services provided by the server core.
The services provided by the server includes:
- Service to direct commands from a client to the plugin (XML-formatted)
- API to decode XML commands
- Access to specific data sources - e.g. odometry pose, laser scans or camera images.
- API for global variable creation and access - for parameter configuration and module status.
- Access to data from other plug-ins
- API to call functions in other plug-ins
- API to allow other plug-ins to call this plug-in
[edit] Minimum plugin
A minimum plug-in can reply to a command and show a bit of online help.
Two codefiles and a Makefile is needed (see the minimum directory in the code)
Makefile ufuncminimum.h ufuncminimum.cpp
[edit] Class definition
The ufuncminimum.h defines the UFuncMinimum plug-in class as
class UFuncMinimum : public UFuncPlugBase { public: UFuncMinimum() { // command list and version text setCommand("minimum", "minimum plugin example"); } virtual bool handleCommand(UServerInMsg * msg, void * extra); };
The class enherits all the needed core functionality from UFuncPlugBase. The plugin gets the command key-name minimum from the setCommand(..) call in the class constructor.
When the server gets a command with the keyword minimum it calls the function
bool handleCommand(UServerInMsg * msg, void * extra);
This function has two parameters, the command message itself in msg and an extra parameter used in some event-related commands, and may point to the data structure related to the event (push commands).
[edit] Method implementation
The ufuncminimum.cpp file defines the handleCommand(...) method. In this case it looks like this:
1 #include "ufuncminimum.h" 2 #ifdef LIBRARY_OPEN_NEEDED 3 UFunctionBase * createFunc() 4 { // create an object of this type 5 return new UFuncMinimum(); 6 } 7 #endif 8 9 bool UFuncMinimum::handleCommand(UServerInMsg * msg, void * extra) 10 { 11 const int MRL = 500; 12 char reply[MRL]; 13 bool ask4help; 14 double a = 100.0, b = 100.0; 15 // 16 ask4help = msg->tag.getAttValue("help", NULL, 0); 17 msg->tag.getAttDouble("a", &a, a); 18 msg->tag.getAttDouble("b", &b, b); 19 // 20 if (ask4help) 21 { // create the reply in XML-like (html - like) format 22 sendHelpStart("MINIMUM"); 23 sendText("--- MINIMUM is a demonstration plug-in that calculates the minimum of two numbers\n"); 24 sendText("a=A Value of A (default is 100)\n"); 25 sendText("b=B Value of B (default is 100)\n"); 26 sendText("help This message\n"); 27 sendHelpDone(); 28 } 29 else 30 { // calculate minimum value 31 snprintf(reply, MRL, "minimum(a=%g, b=%g) is %g", a, b, fmin(a,b)); 32 sendInfo(reply); 33 } 34 return true; 35 }
- The first line is to include the class definition.
- The lines 2-7 defines the function the server calls to create an instance of the UFuncMinimum plug-in class.
The rest (line 16-35) is a simple command handling method, with a recommendable structure:
- Line 16-18 retrives the options from the command line
The msg->tag.getAttValue("help", const char * val, const int valCnt) in line 16 uses the 'tag' structure in the message 'msg'. The tag structure holds the original XML formatted command, and has a few methods to extract values. The basic is to get the value string 'val' (of size valCnt) associated with an attribute. (The tag is an instance of the class USmlTagIn, see the class documentation for the full API)
Line 17 and 18 uses a specialized method (bool tag.getAttDouble("a", &a, a)) to get a double sized value from an attribute named "a". The second parameter is where the value is placed and the third parameter is the default value, used if the value string is empty. (The function returns false if an attribute with this name is not available).
- Line 20-28 is the on-line help reply.
The reply must be packed in the XML format, and this code makes a reply to a minimum help command:
>> minimum help <help subject="MINIMUM"> --- MINIMUM is a demonstration plug-in that calculates the minimum of two numbers a=A Value of A (default is 100) b=B Value of B (default is 100) help This message </help> <minimum info="done"/>
The help text is packed in <help> ... </help> bracket marking that this is intended for on-line help (and not for computer interpretation.
The last tag <minimum info="done"> is to satisfy a handshake that there should always be a reply of the same tag name as the command (in this case minimum). This handshake convension is not mandatory, but provides an indication of that the command is executed.
- line 29-33 is where the real functionality of the plug-in is executed and the replay assembled.
When following is examples on commands and the reply from the minimum plug-in:
>> minimum <minimum info="minimum(a=100, b=100) is 100"/> >> >> minimum A=9 B=8.99 <minimum info="minimum(a=9, b=8.99) is 8.99"/> >> >> minimum b=8.2 <minimum info="minimum(a=100, b=8.2) is 8.2"/> >> >> minimum b=8.2 a=8.3 <minimum info="minimum(a=8.3, b=8.2) is 8.2"/> >> >> <minimum b="8.2" a='8.3'/> <minimum info="minimum(a=8.3, b=8.2) is 8.2"/>
The commands and attribute names are not case sensitive.
In the last example the command is packed as an XML formatted tag, but in the used tag interpreter, the requirement for the tag frame < .../> and the quotes or apostrophes around the values are relaxed. Quotes or apostrophes are mandatory if the value includes a space character.
- line 34 returns true (can return false if the number of calls are important and this command failed, e.g. if no source image is available right now. Number of successful calls can be used in push commands.
[edit] Makefile
The Makefile gives the name of the plug-in and must know which files to compile.
1 libname = minimum.so 2 CPPFLAGS = -I../include 3 LDFLAGS = -g0 -shared -Wl,-soname,$(libname) 4 DEFINES = -D LIBRARY_OPEN_NEEDED 5 CXXFLAGS = -g0 -O2 -Wall -pedantic -fPIC $(DEFINES) 6 7 objects = ufuncminimum.o 8 shlib = $(libname).0 9 10 all: $(objects) 11 c++ -o $(shlib) $(objects) $(LDFLAGS) 12 13 .PHONY : clean install 14 clean : 15 rm -f $(shlib) $(objects) 16 -@rm -fr *~ .deps 17 18 install: 19 cp $(shlib) ../bin 20
The two lines to update for a new plugin is:
- Line 1 defines the name of the plugin minimum.so
libname = minimum.so
- Line 7 defines the compile output-files - in this case just one, compile the ufuncminimum.cpp to ufuncminimum.o.
objects = ufuncminimum.o
The remaining lines can be left unhanged and holds the compile options needed for a plug-in in this environment, and will in most cases detect the dependencies to be recompiled after a change in any of the files.
[edit] Global variables and inter-plug-in calls
See Variables.
The inter-plug-in calls has an alternative implementation that takes UVariable as parameter (for both strings, doubles and arrays) this makes calls simpler in some cases.
@todo describe the call implementation using UVariable parameters.
[edit] Laser scanner access
@todo
[edit] Camera image access
@todo