-
Notifications
You must be signed in to change notification settings - Fork 15
Performing Range Bearing using a CPP client
Louise Poubel edited this page Nov 2, 2021
·
1 revision
To perform range bearing you will need to understand Ignition transport and the acoustic comms layer. The range-bearing protocol uses the underlying Comms architecture to simulate a very basic instance of two way ranging. For an example of how to use range bearing see the following unit test
The RangeBearingPlugin will listen on the /{namespace}/range_bearing/requests
for incoming requests using the lrauv_ignition_plugins::msgs::LRAUVRangeBearingRequest
message and will respond using the lrauv_ignition_plugins::msgs::LRAUVRangeBearingResponse
message on the /{namespace}/range_bearing/response
topic.
The RangeBearingResponse has the following format:
message LRAUVRangeBearingResponse
{
/// \brief Request ID. Each request ID must be unique.
uint32 req_id = 1;
/// \brief Bearing in terms of (r, theta, phi). This is based on ground truth
/// and not calculated using time-of-flight
ignition.msgs.Vector3d bearing = 2;
/// \brief Time-Of-Flight reading. This is good for studying errors arising
/// due to movement. But at high dt this may be prone to error.
double range = 3;
}
This client is the same as the one found in the unit test.
class RangeBearingClient
{
public: RangeBearingClient(std::string namespace) :
request_counter(2)
{
this->pub = this->node.Advertise<msgs::LRAUVRangeBearingRequest>(
"/"+namespace+"/range_bearing/requests");
this->node.Subscribe("/"+namespace+"/range_bearing/responses",
&RangeBearingClient::onRecvResponse,
this
);
}
/// \brief Use this method to range the vehicle with address address
/// \param[\in] address - The address to range with.
public: msgs::LRAUVRangeBearingResponse RequestRange(uint32_t address)
{
// Send a range bearing request targetting <address>
msgs::LRAUVRangeBearingRequest req;
req.set_to(address);
// We use a request counter to help synchronize messages with responses
req.set_req_id(this->request_counter);
// Reset the condition to be waited upon.
this->received = false;
this->pub.Publish(req);
// wait for response
std::unique_lock<std::mutex> lk(this->mtx);
cv.wait(lk, [this]{return this->received;});
// Increment request counter.
this->request_counter++;
return this->lastResponse;
}
/// \brief this callback is called when a response comes in.
public: void onRecvResponse(const msgs::LRAUVRangeBearingResponse& resp)
{
igndbg << "Received message\n";
if(resp.req_id() == this->request_counter)
{
{
std::lock_guard<std::mutex> lk(this->mtx);
this->lastResponse = resp;
this->received = true;
}
cv.notify_all();
}
}
private: ignition::transport::Node node;
private: ignition::transport::Node::Publisher pub;
private: uint32_t request_counter;
private: std::mutex mtx;
private: std::condition_variable cv;
private: msgs::LRAUVRangeBearingResponse lastResponse;
private: bool received;
};