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

From The BABEL Development Site
(Steps)
(Calling getObservations)
Line 18: Line 18:
 
</cpp>
 
</cpp>
  
For doing so, use the following fragment of code, explained in the comments. Pay attention to the label "YOUR CODE HERE"  
+
For doing so, use the following fragment of code, explained in the comments.  
for the place where to process the laser scan.
+
Pay attention to the label "YOUR CODE HERE" for the place where to process the laser scan.
 +
 
 +
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 or inserting the JMS macro from the many and fill the parameters by hand.
 +
 
  
 
<cpp>
 
<cpp>
Line 91: Line 94:
  
 
</cpp>
 
</cpp>
 
  
 
=== Auxiliary code ===
 
=== Auxiliary code ===

Revision as of 21:49, 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.

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 or inserting the JMS macro from the many and fill the parameters by hand.


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