Go to the documentation of this file.00001
00032 #include "nanotron_swarm/cntronbase.h"
00033
00034 #include <rangeonly_msgs/P2PRange.h>
00035
00036 #include <iostream>
00037 #include <unistd.h>
00038 #include <ros/ros.h>
00039
00040 #define DEFAULT_PORT "/dev/ttyUSB0"
00041 #define DEFAULT_FRAME_ID "/base_nanotron"
00042
00043 void detectBeacons(CNTronBase& nodoBase);
00044 bool rangingRequest(CNTronBase& nodoBase, int node, CNTronRange& nodo);
00045 void publishRange(CNTronRange& range, ros::Publisher publisher, std::string frameID);
00046
00047 int main(int argc, char** argv) {
00048
00049 CNTronBase baseNode = CNTronBase();
00050 bool validRange;
00051
00052
00053 ros::init(argc, argv, "nanotron_swarm");
00054 ros::NodeHandle n;
00055 ros::NodeHandle privNode("~");
00056
00057
00058 std::string devicePort = DEFAULT_PORT;
00059 privNode.getParam("device", devicePort);
00060
00061
00062 std::string frameID = DEFAULT_FRAME_ID;
00063 privNode.getParam("frame_id", frameID);
00064
00065
00066 ROS_INFO("Initializing range sensor on %s", devicePort.c_str());
00067 int baseID = baseNode.init(devicePort.c_str());
00068 if (baseID < 0) {
00069 ROS_ERROR("Device initialization error: %s", devicePort.c_str());
00070 } else {
00071 ROS_INFO("The ID of the base node is: %d", baseNode.getBaseId());
00072 }
00073
00074 std::string topic = "range";
00075 privNode.getParam("topic", topic);
00076 ros::Publisher rangePub = n.advertise<rangeonly_msgs::P2PRange>(topic,
00077 1000);
00078 ROS_INFO("Range measurements published on %s", rangePub.getTopic().c_str());
00079
00080
00081 CNTronRange range;
00082
00083
00084 while (ros::ok()) {
00085 detectBeacons(baseNode);
00086
00087 for (unsigned int i = 0; i < baseNode.numBeacons(); i++) {
00088
00089 validRange = rangingRequest(baseNode, i, range);
00090
00091 if (validRange)
00092 publishRange(range, rangePub, frameID);
00093 }
00094 }
00095
00096
00097 baseNode.finish();
00098
00099 return 0;
00100 }
00101
00102 void detectBeacons(CNTronBase& baseNode) {
00103 int result = baseNode.detectBeacons();
00104
00105 switch (result) {
00106 case -1:
00107 ROS_ERROR("Command GetNodeIDList could not be sent.");
00108 break;
00109 case -5:
00110 ROS_ERROR("Empty buffer when reaing the list of available nodes.");
00111 break;
00112 case 0:
00113
00114 break;
00115 default:
00116 ROS_ERROR(
00117 "Unknown error while trying to read the list of available nodes.");
00118 break;
00119 }
00120 }
00121
00122 bool rangingRequest(CNTronBase& baseNode, int node, CNTronRange& range) {
00123
00124 bool valid = false;
00125 std::string msgerr;
00126
00127 int result = baseNode.readRange(node, range, msgerr);
00128
00129 switch (result) {
00130 case 0:
00131 if (!msgerr.empty())
00132 ROS_ERROR("%s", msgerr.c_str());
00133 break;
00134 case -5:
00135 ROS_ERROR("Empty buffer while trying to read a range measurement");
00136 break;
00137 case 1:
00138 valid = true;
00139
00140 ROS_DEBUG("RANGING: Tx %d --> Rx %d => Distance %f m.\n",
00141 range.emitterId, range.beaconId, range.range);
00142 break;
00143 default:
00144 ROS_ERROR("Unknown Error while ranging");
00145 break;
00146 }
00147
00148 return valid;
00149 }
00150
00151 void publishRange(CNTronRange& range, ros::Publisher publisher,
00152 std::string frameID) {
00153
00154 static long sequence = 0;
00155
00156 rangeonly_msgs::P2PRange msg;
00157
00158 msg.header.stamp = ros::Time::now();
00159 msg.header.seq = sequence++;
00160 msg.header.frame_id = frameID;
00161
00162 msg.radiation_type = rangeonly_msgs::P2PRange::RADIO;
00163
00164 msg.emitter_id = range.emitterId;
00165 msg.emitter_type = rangeonly_msgs::P2PRange::BASE;
00166
00167 msg.receiver_id = range.beaconId;
00168 msg.receiver_type = rangeonly_msgs::P2PRange::BEACON;
00169
00170 msg.range = (double) range.range;
00171 msg.variance = 2.25;
00172
00173 publisher.publish(msg);
00174
00175 }