Difference between revisions of "Architecture Tutorial: Retrieve laser scans"
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
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.
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 explained here.