Difference between revisions of "Architecture Tutorial: Retrieve laser scans"
 (→Overview)  | 
				 (→Calling getObservations)  | 
				||
| Line 15: | Line 15: | ||
=== Calling ''getObservations'' ===  | === Calling ''getObservations'' ===  | ||
| − | At the point in your module where you need to request the laser scans,   | + | At the point in your module where you need to request the laser scans, the service "getObservations" from "BS_RangeSensors" must be invoked. This is the definition of that service, just to know how it looks like:  | 
| − | <  | + | <center>  | 
| − | ::  | + | [[Image:tut-scans_service.jpg]]  | 
| − | out   | + | </center>  | 
| − | + | ||
| − | + | ||
| − | </  | + | To call that service, '''you must use the aracne-atom "request-synchronous&blocking"'''. It can be inserted in your code from the BABEL_MD menu.  | 
| + | A dialog will appear asking you which module and service you want to call. Write this information by hand or by using the button "From ICE..." as in the image:  | ||
| + | |||
| + | <center>  | ||
| + | [[Image:tut-scans_wizard1.jpg]]  | ||
| + | </center>  | ||
| + | |||
| + | Accept and a wizard will appear asking you for the arguments of the service. Fill it out as in the figure:  | ||
| + | |||
| + | <center>  | ||
| + | [[Image:tut-scans_wizard2.jpg]]  | ||
| + | </center>  | ||
| + | |||
| + | |||
| + | Now, this aracne atom must have some preparatory C++ code '''before''' it, and some C++ code '''after''' it to process the results.   | ||
| − | + | You can use the following fragments of code, self-explained in its comments.    | |
| − | Pay attention to   | + | '''Pay attention to''':  | 
| + | * The label "YOUR CODE HERE" for the place where to process the laser scan.  | ||
| + | * The point "ARACNE_ATOM_HERE" at which the aracne atom "request-synchronous&blocking" must be inserted.    | ||
Also, note that the macro #JMS-INCLUDE()#, if not inserted through the BABEL menu will NOT automatically add the dependency to your module, so it is recommended to either add the dependency on "BS_RangeSensors::getObservations" manually (first BABEL_MD tab, "Deps" button) or to insert the JMS macro from the menu and fill the parameters by hand (see the correct order of the parameters in the code below).  | Also, note that the macro #JMS-INCLUDE()#, if not inserted through the BABEL menu will NOT automatically add the dependency to your module, so it is recommended to either add the dependency on "BS_RangeSensors::getObservations" manually (first BABEL_MD tab, "Deps" button) or to insert the JMS macro from the menu and fill the parameters by hand (see the correct order of the parameters in the code below).  | ||
| Line 41: | Line 57: | ||
bool err_var;                              // BABEL communication error?  | bool err_var;                              // BABEL communication error?  | ||
| − | + | /** ARACNE_ATOM_HERE  **/  | |
// Error? Propagate it:  | // Error? Propagate it:  | ||
if (err_var)  | if (err_var)  | ||
{  | {  | ||
| − | + | 	// process error  | |
}  | }  | ||
| Line 69: | Line 85: | ||
	catch(std::exception &e)  | 	catch(std::exception &e)  | ||
	{  | 	{  | ||
| − | + | 		// Process ERROR, message in e.what()  | |
	}  | 	}  | ||
}  | }  | ||
| Line 89: | Line 105: | ||
	// Access to the object data members to get the scan data.  | 	// Access to the object data members to get the scan data.  | ||
	// Refer to: http://babel.isa.uma.es/mrpt/reference/svn/classmrpt_1_1slam_1_1_c_observation2_d_range_scan.html  | 	// Refer to: http://babel.isa.uma.es/mrpt/reference/svn/classmrpt_1_1slam_1_1_c_observation2_d_range_scan.html  | ||
| − | 	//   | + | 	// Examples:  | 
| − | + | 	//   Scan size: laserScan->scan.size()  | |
| − | + | 	//   Scan point[0]: laserScan->scan[0]  | |
| − | + | 	//   Scan point[0] is valid: laserScan->validRange[0]!=0  | |
}  | }  | ||
else  | else  | ||
Revision as of 09:18, 23 July 2009
Contents
Overview
Following the Robotic Architecture proposed here, laser scans from either a simulated or a real robot should be accessible from a single module, named BS_RangeSensors.
The interface of this module is described in this section and this tutorial explains how to write a client module to query the latest laser scans from BS_RangeSensors.
Notice that this tutorial only covers the specific case of implementing a module with the C/C++ language.
Steps
Calling getObservations
At the point in your module where you need to request the laser scans, the service "getObservations" from "BS_RangeSensors" must be invoked. This is the definition of that service, just to know how it looks like:
To call that service, you must use the aracne-atom "request-synchronous&blocking". It can be inserted in your code from the BABEL_MD menu.
A dialog will appear asking you which module and service you want to call. Write this information by hand or by using the button "From ICE..." as in the image:
Accept and a wizard will appear asking you for the arguments of the service. Fill it out as in the figure:
Now, this aracne atom must have some preparatory C++ code before it, and some C++ code after it to process the results. 
You can use the following fragments of code, self-explained in its comments. Pay attention to:
- The label "YOUR CODE HERE" for the place where to process the laser scan.
 - The point "ARACNE_ATOM_HERE" at which the aracne atom "request-synchronous&blocking" must be inserted.
 
Also, note that the macro #JMS-INCLUDE()#, if not inserted through the BABEL menu will NOT automatically add the dependency to your module, so it is recommended to either add the dependency on "BS_RangeSensors::getObservations" manually (first BABEL_MD tab, "Deps" button) or to insert the JMS macro from the menu and fill the parameters by hand (see the correct order of the parameters in the code below).
<cpp>
using namespace mrpt;
using namespace mrpt::utils;
using namespace mrpt::slam;
// Retrieve the latest laser scan // ----------------------------------------------------- BABEL::BS_RangeSensors::SeqOfBytes *SF; // The sequence of bytes sent by the server module BABEL::Boolean sensorError; // Sensor error? bool err_var; // BABEL communication error?
/** ARACNE_ATOM_HERE **/
// Error? Propagate it: if (err_var) { // process error }
CObservation2DRangeScanPtr laserScan; // A smart-pointer to the laser scan (read below)
if (!err_var && !sensorError) { try { // De-serialize the object: mrpt::utils::CSerializablePtr obj = SeqOfBytes2MRPTObject(SF);
// Assure it's a valid observation: ASSERT_(obj) ASSERT_( IS_CLASS(obj,CSensoryFrame) )
CSensoryFramePtr theSF = CSensoryFramePtr(obj);
laserScan = theSF->getObservationByClass<CObservation2DRangeScan>(); // Get the first scan, if any. } catch(std::exception &e) { // Process ERROR, message in e.what() } }
// Free memory of the Sequence if (!err_var) { delete SF; SF = NULL; }
// Now, we have the latest scan laser in the variable "laserScan", which 
//  is a smart pointer to a mrpt::slam::CObservation2DRangeScan
// -------------------------------------------------------------------------
if (laserScan)
{
	// ******* YOUR CODE HERE **************
	// Access to the object data members to get the scan data.
	// Refer to: http://babel.isa.uma.es/mrpt/reference/svn/classmrpt_1_1slam_1_1_c_observation2_d_range_scan.html
	// Examples:
	//   Scan size: laserScan->scan.size()
	//   Scan point[0]: laserScan->scan[0]
	//   Scan point[0] is valid: laserScan->validRange[0]!=0
}
else
{
	// For some reason (comms error, hardware error, etc...) there is no laser scan.
}
</cpp>
Auxiliary code
Add the following auxiliary function to your module "Auxiliary logic" section, since this function is used in the code above:
<cpp> // SeqOfBytes2MRPTObject: Convert a BABEL sequence of bytes into a MRPT object. // IMPORTANT: "T of seqofbytes" must be a POINTER to a BABEL sequence, not a reference to it. template <typename T> mrpt::utils::CSerializablePtr SeqOfBytes2MRPTObject(const T &seqofbytes) { if (seqofbytes->length()==0) return mrpt::utils::CSerializablePtr(); mrpt::utils::CMemoryStream memBlock;
memBlock.assignMemoryNotOwn(&(*seqofbytes)[0], seqofbytes->length() );
return memBlock.ReadObject(); } </cpp>
Non-deportabilities of the module
If your module didn't use MRPT before adding these code fragments, it must be inserted by:
- Selecting the tab "Non-deportabilities" in BABEL_MD.
 - Select "Execution".
 - Add "mrpt-core" from the list below.
 - Save the module.
 
You'll need MRPT installed as explained here.


