C++
--
Questions
--
Followers
Top Experts
i'm using Boost Asio library to have a UDP Server which receives commands from a UDP Clients and follow the received instructions to control a robot.
I'd like to check if the Server loose the connection in order to immediately stop the robot but i'm not able to know what i have to do to detect when i loose a connection.
At the moment, i use this code for UDP Server:
void server(boost::asio::io_service& io_service, short port)
{
udp::socket sock(io_service, udp::endpoint(udp::v4(), port));
std::cout << "\n**Accepted connection**\n";
for (;;)
{
char data[max_length];
udp::endpoint sender_endpoint;
size_t length = sock.receive_from(
boost::asio::buffer(data, max_length), sender_endpoint);
sock.send_to(boost::asio::buffer(data, length), sender_endpoint);
..
... robot control routine ...
}
}
int main(int argc, char **argv)
{
boost::asio::io_service io_service;
server(io_service, porta);
... // other functions
}
What i have to do in order to check the lost client connection?I have to use try..catch structure? but.. where?
Thanks to all!
Deleted by SouthMod, no points refunded: 8/25/2011 3:50:00 AM
Zero AI Policy
We believe in human intelligence. Our moderation policy strictly prohibits the use of LLM content in our Q&A threads.
So i think the best choice is to use a timeout treshold because i prefer to not send extra packets.
What's the best way to implement a timeout treshold in C/C++?
I think i should add this to the socket reading message block code, is it true?
clock_t prev = clock();
clock_t now;
double interval;
for (;;)
{
char data[max_length];
udp::endpoint sender_endpoint;
size_t length = sock.receive_from(
boost::asio::buffer(data, max_length), sender_endpoint);
sock.send_to(boost::asio::buffer(data, length), sender_endpoint);
now = clock();
interval = (double)(now -prev) / CLOCKS_PER_SEC;
if (interval > MAX_INTERVAL) { // define MAX_INTERVAL according to your needs
// timeout, stop.
}
prev = now; // store for next comparison
..
... robot control routine ...
}
You are really great! :)
As soon as it is possible i test this solution on my robot: the problem is that sometimes there are some delays even when the client application is up so i have to test if the time checking over the packets can work and manage the delays but i think it can because UDP seems to be faster.






EARN REWARDS FOR ASKING, ANSWERING, AND MORE.
Earn free swag for participating on the platform.
I tested it today with no good result because when the server receives data from client, both prev and now variables increase their values, but if i close the client, then these values doesn't change anymore and so i can't check if client is close or not.
This happens because prev and now are pretty similar and so interval is always 0 or 0.1 at max and when i close the client this value does not change.
void server(boost::asio::io_service& io_service, short port)
{
udp::socket sock(io_service, udp::endpoint(udp::v4(), port));
std::cout << "\n**Connessione Accettata**\n";
std::cout << "\nOffset: " << offset << "\nDistanza Minima: " << distanza_minima << "\n";
prev = clock();
for (;;)
{
char data[max_length];
udp::endpoint sender_endpoint;
size_t length = sock.receive_from(
boost::asio::buffer(data, max_length), sender_endpoint);
sock.send_to(boost::asio::buffer(data, length), sender_endpoint);
now = clock();
data[length] = 0;
output = GetValueFromLine(data);
interval = (double)(now - prev) / CLOCKS_PER_SEC;
if (interval > MAX_INTERVAL){
// stop
}
prev = now;
printf("\nInterval %f Prev: %f Now %f\n", interval, (double)prev/CLOCKS_PER_SEC, (double) now / CLOCKS_PER_SEC);
// control routine
}
int main(int argc, char **argv)
{
//some other code here
boost::asio::io_service io_service;
server(io_service, porta);
return 0;
}

Get a FREE t-shirt when you ask your first question.
We believe in human intelligence. Our moderation policy strictly prohibits the use of LLM content in our Q&A threads.
I added it just for a test, but the server process does not send back any information to the client one.






EARN REWARDS FOR ASKING, ANSWERING, AND MORE.
Earn free swag for participating on the platform.
Yes, the strange it's that as soon as the server start, it prints: "Accepted connection" even if the client isn't up in that moment.
When the client closes, there is not timeout and it waits until next packets arrive in fact if i reconnect the client and i try to send packets, the prev and now variable continue to increase their value.
clock_t prev = 0; // GLOBAL variable!
void alarm_handler_to_check_timeout(int);
//...
// set handler
signal(SIGALRM,alarm_handler_to_check_timeout);
for (;;)
{
char data[max_length];
udp::endpoint sender_endpoint;
size_t length = sock.receive_from(
boost::asio::buffer(data, max_length), sender_endpoint);
sock.send_to(boost::asio::buffer(data, length), sender_endpoint);
prev = clock(); // store for next comparison
..
... robot control routine ...
}
void alarm_handler_to_check_timeout(int) {
clock_t now;
double interval;
now = clock();
interval = (double)(now -prev) / CLOCKS_PER_SEC;
if (interval > MAX_INTERVAL) { // define MAX_INTERVAL according to your needs
// timeout, stop.
}
}
Application seems to never reach the alarm_handler_to_check_tim
void alarm_handler_to_check_timeout(int) {
clock_t now;
double interval;
now = clock();
printf("\nNow: %f Prev: %f\n", (double)now, (double)prev);
interval = (double)(now -prev) / CLOCKS_PER_SEC;
if (interval > MAX_INTERVAL) { // define MAX_INTERVAL according to your needs
printf("\nDentro STOP condition\n"); // timeout, stop.
}
}
void server(boost::asio::io_service& io_service, short port)
{
udp::socket sock(io_service, udp::endpoint(udp::v4(), port));
std::cout << "\nConnection accepted\n";
signal(SIGALRM,alarm_handler_to_check_timeout);
for (;;)
{
char data[max_length];
udp::endpoint sender_endpoint;
size_t length = sock.receive_from(
boost::asio::buffer(data, max_length), sender_endpoint);
sock.send_to(boost::asio::buffer(data, length), sender_endpoint);
data[length] = 0;
output = GetValueFromLine(data);
prev = clock();
// control routine
}
}
Application never writes the printf statement in the alarm_handler_to_check_tim
I don't know why because if i well understood, when application signals SIGALRM it calls the timeout() function but this seems to not happen.

Get a FREE t-shirt when you ask your first question.
We believe in human intelligence. Our moderation policy strictly prohibits the use of LLM content in our Q&A threads.
I'll get you back in a while :)
So, if while the client is running interval is for example interval = 0.4, then after i close the client, interval is still equals to 0.4 and it does not increase its value.
Interval: 0.000000 Now: 0.000000 Prev: 0.000000
Interval: 0.000000 Now: 0.000000 Prev: 0.000000
Interval: 0.000000 Now: 30000.000000 Prev: 0.000000
Interval: 0.030000 Now: 30000.000000 Prev: 0.000000
Interval: 0.030000 Now: 30000.000000 Prev: 0.000000
Interval: 0.030000 Now: 30000.000000 Prev: 0.000000
Interval: 0.030000 Now: 30000.000000 Prev: 0.000000
Interval: 0.030000 Now: 30000.000000 Prev: 0.000000
Taking readings from the 181 laser values
Interval: 0.030000 Now: 30000.000000 Prev: 0.000000
Interval: 0.030000 Now: 30000.000000 Prev: 0.000000
Interval: 0.030000 Now: 30000.000000 Prev: 0.000000
Interval: 0.030000 Now: 30000.000000 Prev: 0.000000
Interval: 0.030000 Now: 30000.000000 Prev: 0.000000
Taking readings from the 181 laser values
Interval: 0.030000 Now: 30000.000000 Prev: 0.000000
Interval: 0.030000 Now: 30000.000000 Prev: 0.000000
Taking readings from the 181 laser values
Interval: 0.030000 Now: 30000.000000 Prev: 0.000000
Interval: 0.030000 Now: 30000.000000 Prev: 0.000000
Interval: 0.030000 Now: 30000.000000 Prev: 0.000000
Interval: 0.030000 Now: 30000.000000 Prev: 0.000000
Interval: 0.030000 Now: 30000.000000 Prev: 0.000000
Interval: 0.030000 Now: 30000.000000 Prev: 0.000000
Taking readings from the 181 laser values
Interval: 0.030000 Now: 30000.000000 Prev: 0.000000
Taking readings from the 181 laser values
Interval: 0.030000 Now: 30000.000000 Prev: 0.000000
Interval: 0.030000 Now: 30000.000000 Prev: 0.000000
Interval: 0.030000 Now: 30000.000000 Prev: 0.000000
Interval: 0.030000 Now: 30000.000000 Prev: 0.000000
Interval: 0.030000 Now: 30000.000000 Prev: 80000.000000
Interval: 0.030000 Now: 30000.000000 Prev: 80000.000000
Interval: 0.030000 Now: 30000.000000 Prev: 80000.000000
Interval: 0.030000 Now: 30000.000000 Prev: 80000.000000
Interval: 0.030000 Now: 30000.000000 Prev: 80000.000000
Interval: 0.030000 Now: 30000.000000 Prev: 80000.000000
Taking readings from the 181 laser values
Interval: 0.030000 Now: 30000.000000 Prev: 90000.000000
Interval: 0.030000 Now: 30000.000000 Prev: 90000.000000
Interval: 0.030000 Now: 30000.000000 Prev: 90000.000000
Warning: ArRobot sync tasks too long at 351 ms, (100 ms normal 250 ms warning)
Interval: 0.030000 Now: 30000.000000 Prev: 90000.000000
Interval: 0.030000 Now: 30000.000000 Prev: 90000.000000
Taking readings from the 181 laser values
Interval: 0.030000 Now: 30000.000000 Prev: 90000.000000
Interval: 0.030000 Now: 30000.000000 Prev: 100000.000000
Interval: 0.030000 Now: 30000.000000 Prev: 100000.000000
Taking readings from the 181 laser values
Interval: 0.030000 Now: 30000.000000 Prev: 100000.000000
Interval: 0.030000 Now: 30000.000000 Prev: 110000.000000
Interval: 0.030000 Now: 30000.000000 Prev: 110000.000000
Interval: 0.030000 Now: 30000.000000 Prev: 110000.000000
Interval: 0.030000 Now: 30000.000000 Prev: 110000.000000
Taking readings from the 181 laser values
Interval: 0.030000 Now: 30000.000000 Prev: 110000.000000
Interval: 0.030000 Now: 30000.000000 Prev: 110000.000000
Interval: 0.030000 Now: 30000.000000 Prev: 110000.000000
Taking readings from the 181 laser values
Interval: 0.030000 Now: 30000.000000 Prev: 110000.000000
Interval: 0.030000 Now: 30000.000000 Prev: 120000.000000
Interval: 0.030000 Now: 30000.000000 Prev: 120000.000000
Interval: 0.030000 Now: 30000.000000 Prev: 120000.000000
Interval: 0.030000 Now: 30000.000000 Prev: 120000.000000
Taking readings from the 181 laser values
Interval: 0.030000 Now: 30000.000000 Prev: 120000.000000
Interval: 0.030000 Now: 30000.000000 Prev: 120000.000000
Interval: 0.030000 Now: 30000.000000 Prev: 120000.000000
Interval: 0.030000 Now: 30000.000000 Prev: 130000.000000
Taking readings from the 181 laser values
Interval: 0.030000 Now: 30000.000000 Prev: 130000.000000
Interval: 0.030000 Now: 30000.000000 Prev: 130000.000000
Interval: 0.030000 Now: 30000.000000 Prev: 130000.000000
Taking readings from the 181 laser values
Interval: 0.030000 Now: 30000.000000 Prev: 130000.000000
Interval: 0.030000 Now: 30000.000000 Prev: 130000.000000
Interval: 0.030000 Now: 30000.000000 Prev: 130000.000000
Interval: 0.030000 Now: 30000.000000 Prev: 130000.000000
Taking readings from the 181 laser values
Interval: 0.030000 Now: 30000.000000 Prev: 130000.000000
Interval: 0.030000 Now: 30000.000000 Prev: 130000.000000
Interval: 0.030000 Now: 30000.000000 Prev: 130000.000000
Interval: 0.030000 Now: 30000.000000 Prev: 140000.000000
Taking readings from the 181 laser values
Interval: 0.030000 Now: 30000.000000 Prev: 140000.000000
Interval: 0.030000 Now: 30000.000000 Prev: 140000.000000
Interval: 0.030000 Now: 30000.000000 Prev: 140000.000000
Taking readings from the 181 laser values
Interval: 0.030000 Now: 30000.000000 Prev: 140000.000000
Interval: 0.030000 Now: 30000.000000 Prev: 140000.000000
Interval: 0.030000 Now: 30000.000000 Prev: 150000.000000
Interval: 0.030000 Now: 30000.000000 Prev: 150000.000000
Interval: 0.030000 Now: 30000.000000 Prev: 150000.000000
Taking readings from the 181 laser values
Interval: 0.030000 Now: 30000.000000 Prev: 150000.000000
Taking readings from the 181 laser values
Interval: 0.030000 Now: 30000.000000 Prev: 150000.000000
Interval: 0.030000 Now: 30000.000000 Prev: 150000.000000
Interval: 0.030000 Now: 30000.000000 Prev: 150000.000000
Interval: 0.030000 Now: 30000.000000 Prev: 170000.000000
Interval: 0.030000 Now: 30000.000000 Prev: 170000.000000
Taking readings from the 181 laser values
Interval: 0.030000 Now: 30000.000000 Prev: 170000.000000 <<< CLIENT DISCONNECTED
Interval: 0.030000 Now: 30000.000000 Prev: 170000.000000
Interval: 0.030000 Now: 30000.000000 Prev: 170000.000000
Interval: 0.030000 Now: 30000.000000 Prev: 170000.000000
Taking readings from the 181 laser values
Interval: 0.030000 Now: 30000.000000 Prev: 170000.000000
Interval: 0.030000 Now: 30000.000000 Prev: 170000.000000
Taking readings from the 181 laser values
Interval: 0.030000 Now: 30000.000000 Prev: 170000.000000
Interval: 0.030000 Now: 30000.000000 Prev: 170000.000000
Interval: 0.030000 Now: 30000.000000 Prev: 170000.000000
Interval: 0.030000 Now: 30000.000000 Prev: 170000.000000
Taking readings from the 181 laser values
Interval: 0.030000 Now: 30000.000000 Prev: 170000.000000
Taking readings from the 181 laser values
Interval: 0.030000 Now: 30000.000000 Prev: 170000.000000
Interval: 0.030000 Now: 30000.000000 Prev: 170000.000000
Interval: 0.030000 Now: 30000.000000 Prev: 170000.000000
Interval: 0.030000 Now: 30000.000000 Prev: 170000.000000
Interval: 0.030000 Now: 30000.000000 Prev: 170000.000000
Taking readings from the 181 laser values
Interval: 0.030000 Now: 30000.000000 Prev: 170000.000000
Interval: 0.030000 Now: 30000.000000 Prev: 170000.000000
Interval: 0.030000 Now: 30000.000000 Prev: 170000.000000
Taking readings from the 181 laser values
Interval: 0.030000 Now: 30000.000000 Prev: 170000.000000
Interval: 0.030000 Now: 30000.000000 Prev: 170000.000000
Taking readings from the 181 laser values
Interval: 0.030000 Now: 30000.000000 Prev: 170000.000000
When client is disconnected, values does not change anymore so i can't detect if client is up or not.






EARN REWARDS FOR ASKING, ANSWERING, AND MORE.
Earn free swag for participating on the platform.
void alarm_handler_to_check_timeout(int) {
now = clock();
printf("\nInterval: %f Now: %f Prev: %f\n", interval, (double)now, (double)prev);
interval = (double)(now - prev) / CLOCKS_PER_SEC;
if (interval > MAX_INTERVAL) { // define MAX_INTERVAL according to your needs
printf("\nDentro STOP condition\n"); // timeout, stop.
}
}
void server(boost::asio::io_service& io_service, short port)
{
udp::socket sock(io_service, udp::endpoint(udp::v4(), port));
std::cout << "\n**Connessione Accettata**\n";
std::cout << "\nOffset: " << offset << "\nDistanza Minima: " << distanza_minima << "\n";
alarm(1);
signal(SIGALRM,alarm_handler_to_check_timeout);
for (;;)
{
char data[max_length];
udp::endpoint sender_endpoint;
size_t length = sock.receive_from(
boost::asio::buffer(data, max_length), sender_endpoint);
data[length] = 0;
output = GetValueFromLine(data);
prev = clock();
}
}
signal(SIGALRM,alarm_handler_to_check_timeout);
alarm(1);
void server(boost::asio::io_service& io_service, short port)
{
signal(SIGALRM,alarm_handler_to_check_timeout);
alarm(1);
udp::socket sock(io_service, udp::endpoint(udp::v4(), port));
std::cout << "\n**Connessione Accettata**\n";
std::cout << "\nOffset: " << offset << "\nDistanza Minima: " << distanza_minima << "\n";
for (;;)
{
char data[max_length];
udp::endpoint sender_endpoint;
size_t length = sock.receive_from(
boost::asio::buffer(data, max_length), sender_endpoint);
data[length] = 0;
output = GetValueFromLine(data);
prev = clock();
but nothing change.
The problem is that after the first packet, the prev variable start to increase and now variable still have the same value which is equals to interval and not to interval = now - prev. It seems to display just interval = now.
When i close the client, interval is still equals to now and prev have the last value acquired before the client stop.
It would be fine to have a counter which counts how many seconds there are between prev and the global time in order to see if the difference between the last prev time and the global time and if it's greater than MAX_TIME then stop the robot.

Get a FREE t-shirt when you ask your first question.
We believe in human intelligence. Our moderation policy strictly prohibits the use of LLM content in our Q&A threads.
void alarm_handler_to_check_timeout(int) {
clock_t now;
double interval;
now = clock();
printf("\nNow: %f Prev: %f\n", (double)now, (double)prev);
interval = (double)(now -prev) / CLOCKS_PER_SEC;
if (interval > MAX_INTERVAL) { // define MAX_INTERVAL according to your needs
printf("\nDentro STOP condition\n"); // timeout, stop.
}
prev = now; // this line should fix the issue
}
void server(boost::asio::io_service& io_service, short port)
{
udp::socket sock(io_service, udp::endpoint(udp::v4(), port));
std::cout << "\n**Connessione Accettata**\n";
std::cout << "\nOffset: " << offset << "\nDistanza Minima: " << distanza_minima << "\n";
signal(SIGALRM,alarm_handler_to_check_timeout);
alarm(1); // it's the same if i unsert
for (;;)
{
char data[max_length];
udp::endpoint sender_endpoint;
size_t length = sock.receive_from(
boost::asio::buffer(data, max_length), sender_endpoint);
data[length] = 0;
output = GetValueFromLine(data);
prev = clock();
comando = output.sName;
valore = output.nNumber;
// control routine
}
}
void alarm_handler_to_check_timeout(int) {
now = clock();
printf("\nHndler_Interval: %f Now: %f Prev: %f\n", interval, (double)now, (double)prev);
interval = (double)(now - prev) / CLOCKS_PER_SEC;
if (interval > MAX_INTERVAL) { // define MAX_INTERVAL according to your needs
printf("\nDentro STOP condition\n"); // timeout, stop.
}
prev = now;
}
The problem is that interval does not appear to update: when server starts, now variable count the first second and then it never changes its value while prev variable starts to increase the value but if i stop the client, prev remains to the last value and interval does not update.
In this way, i have only a global time value.
This is the output, last three lines are generated after the client closure.
Interval: 0.040000 Now: 0.040000 Prev: 0.040000
Interval: 0.040000 Now: 0.040000 Prev: 0.040000
Interval: 0.040000 Now: 0.040000 Prev: 0.290000
Interval: 0.040000 Now: 0.040000 Prev: 0.290000
Interval: 0.040000 Now: 0.040000 Prev: 0.290000
Interval: 0.040000 Now: 0.040000 Prev: 0.290000
Interval: 0.040000 Now: 0.040000 Prev: 0.290000
Taking readings from the 181 laser values
Interval: 0.040000 Now: 0.040000 Prev: 0.290000
Interval: 0.040000 Now: 0.040000 Prev: 0.290000
Interval: 0.040000 Now: 0.040000 Prev: 0.290000
Interval: 0.040000 Now: 0.040000 Prev: 0.290000
Taking readings from the 181 laser values
Interval: 0.040000 Now: 0.040000 Prev: 0.290000
Interval: 0.040000 Now: 0.040000 Prev: 0.300000
Interval: 0.040000 Now: 0.040000 Prev: 0.300000
Taking readings from the 181 laser values
Interval: 0.040000 Now: 0.040000 Prev: 0.300000
Interval: 0.040000 Now: 0.040000 Prev: 0.300000
Interval: 0.040000 Now: 0.040000 Prev: 0.300000
Interval: 0.040000 Now: 0.040000 Prev: 0.300000
Taking readings from the 181 laser values
Interval: 0.040000 Now: 0.040000 Prev: 0.310000
Interval: 0.040000 Now: 0.040000 Prev: 0.310000
Interval: 0.040000 Now: 0.040000 Prev: 0.310000
Interval: 0.040000 Now: 0.040000 Prev: 0.310000
Interval: 0.040000 Now: 0.040000 Prev: 0.310000
Taking readings from the 181 laser values
Interval: 0.040000 Now: 0.040000 Prev: 0.310000
Interval: 0.040000 Now: 0.040000 Prev: 0.330000
Interval: 0.040000 Now: 0.040000 Prev: 0.330000
Interval: 0.040000 Now: 0.040000 Prev: 0.330000
Interval: 0.040000 Now: 0.040000 Prev: 0.330000
Taking readings from the 181 laser values
Interval: 0.040000 Now: 0.040000 Prev: 0.330000
Interval: 0.040000 Now: 0.040000 Prev: 0.330000
Interval: 0.040000 Now: 0.040000 Prev: 0.340000
Interval: 0.040000 Now: 0.040000 Prev: 0.340000
Interval: 0.040000 Now: 0.040000 Prev: 0.340000
Interval: 0.040000 Now: 0.040000 Prev: 0.340000
Taking readings from the 181 laser values
Interval: 0.040000 Now: 0.040000 Prev: 0.340000
Warning: ArRobot sync tasks too long at 251 ms, (100 ms normal 250 ms warning)
Interval: 0.040000 Now: 0.040000 Prev: 0.340000
Taking readings from the 181 laser values
Interval: 0.040000 Now: 0.040000 Prev: 0.350000
Interval: 0.040000 Now: 0.040000 Prev: 0.350000
Taking readings from the 181 laser values
Interval: 0.040000 Now: 0.040000 Prev: 0.350000
Interval: 0.040000 Now: 0.040000 Prev: 0.350000
Interval: 0.040000 Now: 0.040000 Prev: 0.350000
Taking readings from the 181 laser values
Interval: 0.040000 Now: 0.040000 Prev: 0.350000
Interval: 0.040000 Now: 0.040000 Prev: 0.350000
Interval: 0.040000 Now: 0.040000 Prev: 0.350000
Interval: 0.040000 Now: 0.040000 Prev: 0.350000
Taking readings from the 181 laser values
Interval: 0.040000 Now: 0.040000 Prev: 0.350000
Interval: 0.040000 Now: 0.040000 Prev: 0.370000
Interval: 0.040000 Now: 0.040000 Prev: 0.370000
Interval: 0.040000 Now: 0.040000 Prev: 0.370000
Interval: 0.040000 Now: 0.040000 Prev: 0.370000
Taking readings from the 181 laser values
Interval: 0.040000 Now: 0.040000 Prev: 0.370000






EARN REWARDS FOR ASKING, ANSWERING, AND MORE.
Earn free swag for participating on the platform.
This is the code: http://lnx.mangaitalia.net/code/code.cpp
I used also gettimeofday in order to check if it can work, but it doesn't work.
#include <sys/time.h>
#include "Logger.h"
#include "Aria.h"
#include <cstdlib>
#include <iostream>
#include <boost/asio.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/config.hpp>
#include <boost/program_options/detail/config_file.hpp>
#include <boost/program_options/parsers.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/ini_parser.hpp>
#include <boost/bind.hpp>
#include <boost/smart_ptr.hpp>
#include <boost/thread.hpp>
#include <string>
#include <sstream>
#include <set>
#include <sstream>
#include <exception>
#include <fstream>
#include <limits>
#include <stdarg.h>
#include <fcntl.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/time.h>
#include <time.h>
#include <unistd.h>
#include <stdarg.h>
#include <signal.h>
#define MAX_INTERVAL 1
using boost::asio::ip::udp;
using namespace std;
float temp_heading, temp_distance;
struct DataLine {
float nNumber;
std::string sName;
};
DataLine output;
clock_t prev = 0;
clock_t now;
float distanza_minima = 1500;
float offset = 900;
std::string comando;
float valore;
float heading_prova = 0;
float distance_prova = 0;
const int max_length = 100;
int integer_value;
short int porta;
float last_distance = 0.0;
bool discovery = true;
bool right_disc = false;
bool left_disc = false;
bool start = false;
std::string file;
FILE *file_open;
bool call_fprintf = true;
double interval;
timeval t1, t2, tempo;
double elapsedTime;
bool is_equal(float a, float b) {
return (fabs(a - b) < std::numeric_limits<float>::epsilon());
}
ArRobot robot;
ArSick sick;
bool newGoal=false;
ArPose m_goal;
void alarm_handler_to_check_timeout(int);
void load_from_file(void){
boost::property_tree::ptree pt;
boost::property_tree::ini_parser::read_ini("parametri.ini", pt);
porta = pt.get<short int>("Connessione.porta");
distanza_minima = pt.get<float>("Parametri.distanza_minima");
offset = pt.get<float>("Parametri.offset");
file = pt.get<std::string>("File.file");
}
int wrap_fprintf(FILE* str, const char* format, ...) {
int result = 1;
if (call_fprintf) {
va_list args;
va_start(args, format);
result = vfprintf(str, format, args);
va_end(args);
}
else {
/* do nothing */
}
return result;
}
/* A subclass of ArASyncTask, to contain a method that runs in a new thread */
class CControl : public ArASyncTask
{
ArMutex myMutex;
int myCounter;
float m_heading, m_distance;
bool first;
bool flag_heading, flag_distance;
private:
public:
CControl()
{
first=false;
flag_heading=true;
flag_distance=true;
}
void setHeading(float heading)
{
myMutex.lock();
m_heading=heading;
//first=false;
flag_heading=false;
myMutex.unlock();
}
void setDistance(float distance)
{
myMutex.lock();
m_distance=distance;
//first=false;
flag_distance=false;
myMutex.unlock();
}
void* runThread(void*)
{
printf("\nSpostamento X: %f, Y: %f\n", robot.getX(), robot.getY());
wrap_fprintf(file_open," %f, %f, \n",robot.getX(),robot.getY());
while(Aria::getRunning())
{
if(discovery){
// printf("\nRoutine Discovery Avviata\a\n");
robot.setRotVel(4.0);
}
printf("\nInterval: %f Now: %f Prev: %f\n", interval, (double)now/CLOCKS_PER_SEC, (double)prev/CLOCKS_PER_SEC);
elapsedTime = (t2.tv_sec - t1.tv_sec) * 1000.0; // sec to ms
elapsedTime += (t2.tv_usec - t1.tv_usec) / 1000.0; // us to ms
cout << "\n" << elapsedTime << " ms.\n";
if( !flag_heading && !flag_distance)
{
myMutex.lock();
temp_heading=m_heading;
temp_distance=m_distance;
myMutex.unlock();
gettimeofday(&t2, NULL);
if (is_equal(temp_heading, 0.0)){
robot.setRotVel(0.0);
}
else robot.setRotVel(-ArMath::radToDeg(temp_heading));
if( temp_distance <= (distanza_minima + offset) && temp_distance > distanza_minima){
if (last_distance == 0) last_distance = temp_distance;
float delta = temp_distance - last_distance;
if (is_equal(delta, 0.0)) continue; // skip sending
else {
if ( delta > 0.0){
robot.setVel(float(delta/10));
// printf("\n\n**********\n\nAvanzo di %f\n******\n\n", delta);
}
}
last_distance = temp_distance;
}
else if(temp_distance <= distanza_minima || is_equal(temp_distance, 0.0))
robot.setVel(0.0);
else if(temp_distance > (distanza_minima + offset) )
robot.setVel(float(temp_distance/20));
// printf("\nrunThread:: getX=%f getY=%f heading= %f distance = %f rob_vel = %f rob_rot_vel = %f\n",robot.getX(), robot.getY(), ArMath::radToDeg(temp_heading),temp_distance, robot.getVel(),robot.getRotVel());
flag_heading = true;
flag_distance = true;
}
ArUtil::sleep(100);
}
}
/* Lock the mutex object. */
void lockMutex() { myMutex.lock(); }
/* Unlock the mutex object. */
void unlockMutex() { myMutex.unlock(); }
};
CControl control;
DataLine GetValueFromLine(const std::string& sData) {
std::string sName, sInteger;
std::stringstream ss;
DataLine Result;
size_t sz = sData.find('@');
sName = sData.substr(0,sz); // Just in case you need it later
Result.sName = sName;
sInteger = sData.substr(sz + 1,sData.length() - sz);
ss.str(sInteger);
ss >> Result.nNumber;
if (ss.fail()) {
// something went wrong, probably not an integer
}
return Result;
}
void server(boost::asio::io_service& io_service, short port)
{
udp::socket sock(io_service, udp::endpoint(udp::v4(), port));
std::cout << "\n**Connessione Accettata**\n";
std::cout << "\nOffset: " << offset << "\nDistanza Minima: " << distanza_minima << "\n";
signal(SIGALRM,alarm_handler_to_check_timeout);
alarm(1);
for (;;)
{
char data[max_length];
udp::endpoint sender_endpoint;
prev = clock();
size_t length = sock.receive_from(
boost::asio::buffer(data, max_length), sender_endpoint);
if(length == 0) printf("\n\nNONRICEVONULLA\n\n");
data[length] = 0;
output = GetValueFromLine(data);
comando = output.sName;
valore = output.nNumber;
if (output.sName == "right"){
robot.setRotVel(5.0);
robot.setVel(0.0);
// std::cout << "\nSto ricevendo: " << output.sName;
// printf("\nValore di discovery %d\n", discovery);
// printf("\nLEFT\n");
}
else if(output.sName == "left"){
robot.setRotVel(-5.0);
robot.setVel(0.0);
//printf("\nRIGHT\n");
}
else if (output.sName == "heading"){
start = false;
control.setHeading(output.nNumber);
// std::cout << "\nSto ricevendo: " << output.sName << "e heading: " << output.nNumber;
if(output.nNumber > 0) {
discovery = false;
right_disc = false;
left_disc = true;
}
else if(output.nNumber < 0) {
discovery = false;
left_disc = false;
right_disc = true;
}
}
else if (output.sName == "distance"){
start = false;
control.setDistance(output.nNumber);
// std::cout << "\nSto ricevendo: " << output.sName << "e distance: " << output.nNumber;
gettimeofday(&t1, NULL);
}
else printf("\nReceived code error\n");
gettimeofday(&tempo, NULL);
wrap_fprintf(file_open," %f, %f, %f %f %ld\n",robot.getX(),robot.getY(), temp_distance, ArMath::radToDeg(temp_heading), tempo.tv_sec);
}
}
void alarm_handler_to_check_timeout(int) {
now = clock();
printf("\nHndler_Interval: %f Now: %f Prev: %f\n", interval, (double)now, (double)prev);
interval = (double)(now - prev) / CLOCKS_PER_SEC;
if (interval > MAX_INTERVAL) { // define MAX_INTERVAL according to your needs
printf("\nDentro STOP condition\n"); // timeout, stop.
}
}
int main(int argc, char **argv)
{
load_from_file();
file_open = fopen(file.c_str(), "w");
if(file_open == NULL){
perror("Error opening the reports file");
}
wrap_fprintf(file_open," X[mm], Y[mm] Distance[mm]\n");
Aria::init();
ArArgumentParser parser(&argc, argv);
parser.loadDefaultArguments();
ArSimpleConnector simpleConnector(&parser);
ArActionGoto gotoPoseAction("goto");
gotoPoseAction.setCloseDist(50);
ArSonarDevice sonar;
ArAnalogGyro gyro(&robot);
robot.addRangeDevice(&sick);
robot.addRangeDevice(&sonar);
// Make a key handler, so that escape will shut down the program cleanly
ArKeyHandler keyHandler;
Aria::setKeyHandler(&keyHandler);
robot.attachKeyHandler(&keyHandler);
printf("main:: You may press escape to exit\n");
// Collision avoidance actions at higher priority
ArActionLimiterForwards limiterAction("speed limiter near", 300, 600, 250);
ArActionLimiterForwards limiterFarAction("speed limiter far", 300, 1100, 400);
ArActionLimiterTableSensor tableLimiterAction;
robot.addAction(&tableLimiterAction, 100);
robot.addAction(&limiterAction, 95);
robot.addAction(&limiterFarAction, 90);
// Goto action at lower priority
robot.addAction(&gotoPoseAction, 50);
// Stop action at lower priority, so the robot stops if it has no goal
ArActionStop stopAction("stop");
robot.addAction(&stopAction, 40);
// Parse all command line arguments
if (!Aria::parseArgs() || !parser.checkHelpAndWarnUnparsed())
{
Aria::logOptions();
exit(1);
}
// Connect to the robot
if (!simpleConnector.connectRobot(&robot))
{
printf("main:: Could not connect to robot... exiting\n");
Aria::exit(1);
}
robot.runAsync(true);
// turn on the motors, turn off amigobot sounds
robot.enableMotors();
robot.comInt(ArCommands::SOUNDTOG, 0);
simpleConnector.setupLaser(&sick);
sick.runAsync();
if (!sick.blockingConnect())
{
ArLog::log(ArLog::Terse,
"main: Could not connect to SICK laser... exiting\n");
Aria::shutdown();
Aria::exit(1);
}
CLogger logger(&robot, &sick, 10, 1, "laserOdo.log");
control.runAsync();
try{
boost::asio::io_service io_service;
server(io_service, porta);}
catch (std::exception& e)
{
std::cerr << "Exception: " << e.what() << "\n";
}
return 0;
}
Can i ask you what you changed? because i tried to check it and i found that you removed the "prev = now" statement, it is correct? Or did you changed some other things?
Because i already tried to do this the other day but without success because it seems to not work.

Get a FREE t-shirt when you ask your first question.
We believe in human intelligence. Our moderation policy strictly prohibits the use of LLM content in our Q&A threads.
So i can't check it time is elapsing after the client closure.
printf("\nHndler_Interval:
again (maybe with the commands received)?






EARN REWARDS FOR ASKING, ANSWERING, AND MORE.
Earn free swag for participating on the platform.
I have to collect these data in next days because during this week i had some problems at home and i didn't work on my system.
This question has been classified as abandoned and is closed as part of the Cleanup Program. See the recommendation for more details.

Get a FREE t-shirt when you ask your first question.
We believe in human intelligence. Our moderation policy strictly prohibits the use of LLM content in our Q&A threads.
SouthMod
EE Moderator
C++
--
Questions
--
Followers
Top Experts
C++ is an intermediate-level general-purpose programming language, not to be confused with C or C#. It was developed as a set of extensions to the C programming language to improve type-safety and add support for automatic resource management, object-orientation, generic programming, and exception handling, among other features.