Difference between revisions of "Architecture Tutorial: Retrieve laser scans"

From The BABEL Development Site
m (Protected "Architecture Tutorial: Retrieve laser scans" [edit=sysop:move=sysop])
(Steps)
Line 6: Line 6:
  
 
== Steps ==
 
== Steps ==
 +
 +
=== Calling ''getObservations'' ===
 +
 +
At the point in your module where you need to request the laser scans, this service from  BS_RangeSensors must be invoked:
 +
 +
<cpp>
 +
::getObservations(
 +
out SeqOfBytes SF,
 +
out boolean error
 +
)
 +
</cpp>
 +
 +
For doing so, use the following fragment of code, explained in the comments. Pay attention to the label "YOUR CODE HERE"
 +
for the place where to process the laser scan.
 +
 +
<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?
 +
 +
#JMS-INCLUDE(INC_request-synchronous&blocking,"getObservations","BS_RangeSensors","getObservations","REMOTE_BS_RangeSensors_var","SF,sensorError","err_var","0","INF","","","")#
 +
 +
// Error? Propagate it:
 +
if (err_var)
 +
{
 +
std::cerr << "[OnNewRangeData] *** ERROR querying the module *** " << std::endl;
 +
}
 +
 +
 +
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)
 +
{
 +
std::cerr << "Exception parsing binary object: " << std::endl << e.what() << std::endl;
 +
}
 +
}
 +
 +
// 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
 +
// Example:
 +
cout << "Scan size: " << laserScan->scan.size() << endl;
 +
cout << "Scan point[0]: " << laserScan->scan[0] << endl;
 +
cout << "Scan point[0] is valid: " << laserScan->validRange[0]!=0 ? "Yes" : "No" << endl;
 +
}
 +
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 "Auxility 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 [[Documentation:Install | explained here]].

Revision as of 21:47, 22 July 2009

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.

Steps

Calling getObservations

At the point in your module where you need to request the laser scans, this service from BS_RangeSensors must be invoked:

<cpp>

getObservations(

out SeqOfBytes SF, out boolean error ) </cpp>

For doing so, use the following fragment of code, explained in the comments. Pay attention to the label "YOUR CODE HERE" for the place where to process the laser scan.

<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?

  1. JMS-INCLUDE(INC_request-synchronous&blocking,"getObservations","BS_RangeSensors","getObservations","REMOTE_BS_RangeSensors_var","SF,sensorError","err_var","0","INF","","","")#

// Error? Propagate it: if (err_var) { std::cerr << "[OnNewRangeData] *** ERROR querying the module *** " << std::endl; }


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) { std::cerr << "Exception parsing binary object: " << std::endl << e.what() << std::endl; } }

// 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 // Example: cout << "Scan size: " << laserScan->scan.size() << endl; cout << "Scan point[0]: " << laserScan->scan[0] << endl; cout << "Scan point[0] is valid: " << laserScan->validRange[0]!=0 ? "Yes" : "No" << endl; } 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 "Auxility 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.