beautified and style fixes

This commit is contained in:
dave 2018-12-04 10:34:07 -05:00
parent 5f83aa60f6
commit fbb0f108b1
11 changed files with 2239 additions and 2144 deletions

View File

@ -12,9 +12,9 @@
* OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
*/ */
/* /*
* This code was originally written by Stephan Fortune in C code. I, Shane O'Sullivan, * This code was originally written by Stephan Fortune in C code. I, Shane O'Sullivan,
* have since modified it, encapsulating it in a C++ class and, fixing memory leaks and * have since modified it, encapsulating it in a C++ class and, fixing memory leaks and
* adding accessors to the Voronoi Edges. * adding accessors to the Voronoi Edges.
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose without fee is hereby granted, provided that this entire notice * purpose without fee is hereby granted, provided that this entire notice
@ -36,7 +36,6 @@
#include <stdio.h> #include <stdio.h>
#include <algorithm> #include <algorithm>
#ifndef NULL #ifndef NULL
#define NULL 0 #define NULL 0
#endif #endif
@ -45,210 +44,195 @@
#define le 0 #define le 0
#define re 1 #define re 1
struct Freenode
struct Freenode
{ {
struct Freenode *nextfree; struct Freenode* nextfree;
}; };
struct FreeNodeArrayList struct FreeNodeArrayList
{ {
struct Freenode* memory; struct Freenode* memory;
struct FreeNodeArrayList* next; struct FreeNodeArrayList* next;
}; };
struct Freelist struct Freelist
{ {
struct Freenode *head; struct Freenode* head;
int nodesize; int nodesize;
}; };
struct Point struct Point
{ {
float x,y; float x, y;
Point(): x( 0.0 ), y( 0.0 ) { } Point() : x(0.0), y(0.0)
Point( float x, float y ): x( x ), y( y ) { } {
}
Point(float x, float y) : x(x), y(y)
{
}
}; };
// structure used both for sites and for vertices // structure used both for sites and for vertices
struct Site struct Site
{ {
struct Point coord; struct Point coord;
int sitenbr; int sitenbr;
int refcnt; int refcnt;
}; };
struct Edge
struct Edge
{ {
float a,b,c; float a, b, c;
struct Site *ep[2]; struct Site* ep[2];
struct Site *reg[2]; struct Site* reg[2];
int edgenbr; int edgenbr;
int sites[2]; int sites[2];
}; };
struct GraphEdge struct GraphEdge
{ {
float x1,y1,x2,y2; float x1, y1, x2, y2;
int sites[2]; int sites[2];
struct GraphEdge* next; struct GraphEdge* next;
}; };
struct Halfedge
struct Halfedge
{ {
struct Halfedge *ELleft, *ELright; struct Halfedge *ELleft, *ELright;
struct Edge *ELedge; struct Edge* ELedge;
int ELrefcnt; int ELrefcnt;
char ELpm; char ELpm;
struct Site *vertex; struct Site* vertex;
float ystar; float ystar;
struct Halfedge *PQnext; struct Halfedge* PQnext;
}; };
class VoronoiDiagramGenerator class VoronoiDiagramGenerator
{ {
public: public:
VoronoiDiagramGenerator(); VoronoiDiagramGenerator();
~VoronoiDiagramGenerator(); ~VoronoiDiagramGenerator();
bool generateVoronoi(float *xValues, float *yValues, int numPoints, float minX, float maxX, float minY, float maxY, float minDist=0); bool generateVoronoi(float* xValues, float* yValues, int numPoints, float minX, float maxX, float minY, float maxY,
float minDist = 0);
void resetIterator() void resetIterator()
{ {
iteratorEdges = allEdges; iteratorEdges = allEdges;
} }
bool getNext(float& x1, float& y1, float& x2, float& y2, int *s) bool getNext(float& x1, float& y1, float& x2, float& y2, int* s)
{ {
if(iteratorEdges == 0) if (iteratorEdges == 0)
return false; return false;
x1 = iteratorEdges->x1;
x2 = iteratorEdges->x2;
y1 = iteratorEdges->y1;
y2 = iteratorEdges->y2;
std::copy(iteratorEdges->sites, iteratorEdges->sites+2, s);
iteratorEdges = iteratorEdges->next; x1 = iteratorEdges->x1;
x2 = iteratorEdges->x2;
y1 = iteratorEdges->y1;
y2 = iteratorEdges->y2;
std::copy(iteratorEdges->sites, iteratorEdges->sites + 2, s);
return true; iteratorEdges = iteratorEdges->next;
}
return true;
}
private: private:
void cleanup(); void cleanup();
void cleanupEdges(); void cleanupEdges();
char *getfree(struct Freelist *fl); char* getfree(struct Freelist* fl);
struct Halfedge *PQfind(); struct Halfedge* PQfind();
int PQempty(); int PQempty();
struct Halfedge** ELhash;
struct Halfedge *HEcreate(), *ELleft(), *ELright(), *ELleftbnd();
struct Halfedge* HEcreate(struct Edge* e, int pm);
struct Point PQ_min();
struct Halfedge **ELhash; struct Halfedge* PQextractmin();
struct Halfedge *HEcreate(), *ELleft(), *ELright(), *ELleftbnd(); void freeinit(struct Freelist* fl, int size);
struct Halfedge *HEcreate(struct Edge *e,int pm); void makefree(struct Freenode* curr, struct Freelist* fl);
void geominit();
void plotinit();
bool voronoi(int triangulate);
void ref(struct Site* v);
void deref(struct Site* v);
void endpoint(struct Edge* e, int lr, struct Site* s);
void ELdelete(struct Halfedge* he);
struct Halfedge* ELleftbnd(struct Point* p);
struct Halfedge* ELright(struct Halfedge* he);
void makevertex(struct Site* v);
void out_triple(struct Site* s1, struct Site* s2, struct Site* s3);
struct Point PQ_min(); void PQinsert(struct Halfedge* he, struct Site* v, float offset);
struct Halfedge *PQextractmin(); void PQdelete(struct Halfedge* he);
void freeinit(struct Freelist *fl,int size); bool ELinitialize();
void makefree(struct Freenode *curr,struct Freelist *fl); void ELinsert(struct Halfedge* lb, struct Halfedge* newHe);
void geominit(); struct Halfedge* ELgethash(int b);
void plotinit(); struct Halfedge* ELleft(struct Halfedge* he);
bool voronoi(int triangulate); struct Site* leftreg(struct Halfedge* he);
void ref(struct Site *v); void out_site(struct Site* s);
void deref(struct Site *v); bool PQinitialize();
void endpoint(struct Edge *e,int lr,struct Site * s); int PQbucket(struct Halfedge* he);
void clip_line(struct Edge* e);
char* myalloc(unsigned n);
int right_of(struct Halfedge* el, struct Point* p);
void ELdelete(struct Halfedge *he); struct Site* rightreg(struct Halfedge* he);
struct Halfedge *ELleftbnd(struct Point *p); struct Edge* bisect(struct Site* s1, struct Site* s2);
struct Halfedge *ELright(struct Halfedge *he); float dist(struct Site* s, struct Site* t);
void makevertex(struct Site *v); struct Site* intersect(struct Halfedge* el1, struct Halfedge* el2, struct Point* p = 0);
void out_triple(struct Site *s1, struct Site *s2,struct Site * s3);
void PQinsert(struct Halfedge *he,struct Site * v, float offset); void out_bisector(struct Edge* e);
void PQdelete(struct Halfedge *he); void out_ep(struct Edge* e);
bool ELinitialize(); void out_vertex(struct Site* v);
void ELinsert(struct Halfedge *lb, struct Halfedge *newHe); struct Site* nextone();
struct Halfedge * ELgethash(int b);
struct Halfedge *ELleft(struct Halfedge *he);
struct Site *leftreg(struct Halfedge *he);
void out_site(struct Site *s);
bool PQinitialize();
int PQbucket(struct Halfedge *he);
void clip_line(struct Edge *e);
char *myalloc(unsigned n);
int right_of(struct Halfedge *el,struct Point *p);
struct Site *rightreg(struct Halfedge *he); void pushGraphEdge(float x1, float y1, float x2, float y2, int s[2]);
struct Edge *bisect(struct Site *s1,struct Site *s2);
float dist(struct Site *s,struct Site *t);
struct Site *intersect(struct Halfedge *el1, struct Halfedge *el2, struct Point *p=0);
void out_bisector(struct Edge *e); void openpl();
void out_ep(struct Edge *e); void line(float x1, float y1, float x2, float y2, int s[2]);
void out_vertex(struct Site *v); void circle(float x, float y, float radius);
struct Site *nextone(); void range(float minX, float minY, float maxX, float maxY);
void pushGraphEdge(float x1, float y1, float x2, float y2, int s[2]); struct Freelist hfl;
struct Halfedge *ELleftend, *ELrightend;
int ELhashsize;
void openpl(); int triangulate, sorted, plot, debug;
void line(float x1, float y1, float x2, float y2, int s[2]); float xmin, xmax, ymin, ymax, deltax, deltay;
void circle(float x, float y, float radius);
void range(float minX, float minY, float maxX, float maxY);
struct Freelist hfl; struct Site* sites;
struct Halfedge *ELleftend, *ELrightend; int nsites;
int ELhashsize; int siteidx;
int sqrt_nsites;
int nvertices;
struct Freelist sfl;
struct Site* bottomsite;
int triangulate, sorted, plot, debug; int nedges;
float xmin, xmax, ymin, ymax, deltax, deltay; struct Freelist efl;
int PQhashsize;
struct Halfedge* PQhash;
int PQcount;
int PQmin;
struct Site *sites; int ntry, totalsearch;
int nsites; float pxmin, pxmax, pymin, pymax, cradius;
int siteidx; int total_alloc;
int sqrt_nsites;
int nvertices;
struct Freelist sfl;
struct Site *bottomsite;
int nedges; float borderMinX, borderMaxX, borderMinY, borderMaxY;
struct Freelist efl;
int PQhashsize;
struct Halfedge *PQhash;
int PQcount;
int PQmin;
int ntry, totalsearch; FreeNodeArrayList* allMemoryList;
float pxmin, pxmax, pymin, pymax, cradius; FreeNodeArrayList* currentMemoryBlock;
int total_alloc;
float borderMinX, borderMaxX, borderMinY, borderMaxY; GraphEdge* allEdges;
GraphEdge* iteratorEdges;
FreeNodeArrayList* allMemoryList; float minDistanceBetweenSites;
FreeNodeArrayList* currentMemoryBlock;
GraphEdge* allEdges;
GraphEdge* iteratorEdges;
float minDistanceBetweenSites;
}; };
int scomp(const void *p1,const void *p2); int scomp(const void* p1, const void* p2);
#endif #endif

View File

@ -23,149 +23,149 @@
} while (0) } while (0)
namespace buzz_update namespace buzz_update
{ {
static const uint16_t CODE_REQUEST_PADDING = 250; static const uint16_t CODE_REQUEST_PADDING = 250;
static const uint16_t MIN_UPDATE_PACKET = 251; static const uint16_t MIN_UPDATE_PACKET = 251;
static const uint16_t UPDATE_CODE_HEADER_SIZE = 5; static const uint16_t UPDATE_CODE_HEADER_SIZE = 5;
static const uint16_t TIMEOUT_FOR_ROLLBACK = 50; static const uint16_t TIMEOUT_FOR_ROLLBACK = 50;
/*********************/ /*********************/
/* Updater states */ /* Updater states */
/********************/ /********************/
typedef enum { typedef enum {
CODE_RUNNING = 0, // Code executing CODE_RUNNING = 0, // Code executing
CODE_STANDBY, // Standing by for others to update CODE_STANDBY, // Standing by for others to update
} code_states_e; } code_states_e;
/*********************/ /*********************/
/*Message types */ /*Message types */
/********************/ /********************/
typedef enum { typedef enum {
SENT_CODE = 0, // Broadcast code SENT_CODE = 0, // Broadcast code
RESEND_CODE, // ReBroadcast request RESEND_CODE, // ReBroadcast request
} code_message_e; } code_message_e;
/*************************/ /*************************/
/*Updater message queue */ /*Updater message queue */
/*************************/ /*************************/
struct updater_msgqueue_s struct updater_msgqueue_s
{ {
uint8_t* queue; uint8_t* queue;
uint8_t* size; uint8_t* size;
}; };
typedef struct updater_msgqueue_s* updater_msgqueue_t; typedef struct updater_msgqueue_s* updater_msgqueue_t;
struct updater_code_s struct updater_code_s
{ {
uint8_t* bcode; uint8_t* bcode;
uint8_t* bcode_size; uint8_t* bcode_size;
}; };
typedef struct updater_code_s* updater_code_t; typedef struct updater_code_s* updater_code_t;
/**************************/ /**************************/
/*Updater data*/ /*Updater data*/
/**************************/ /**************************/
struct buzz_updater_elem_s struct buzz_updater_elem_s
{ {
/* robot id */ /* robot id */
// uint16_t robotid; // uint16_t robotid;
/*current Bytecode content */ /*current Bytecode content */
uint8_t* bcode; uint8_t* bcode;
/*old Bytecode name */ /*old Bytecode name */
const char* old_bcode; const char* old_bcode;
/*current bcode size*/ /*current bcode size*/
size_t* bcode_size; size_t* bcode_size;
/*Update patch*/ /*Update patch*/
uint8_t* patch; uint8_t* patch;
/* Update patch size*/ /* Update patch size*/
size_t* patch_size; size_t* patch_size;
/*current Bytecode content */ /*current Bytecode content */
uint8_t* standby_bcode; uint8_t* standby_bcode;
/*current bcode size*/ /*current bcode size*/
size_t* standby_bcode_size; size_t* standby_bcode_size;
/*updater out msg queue */ /*updater out msg queue */
updater_msgqueue_t outmsg_queue; updater_msgqueue_t outmsg_queue;
/*updater in msg queue*/ /*updater in msg queue*/
updater_msgqueue_t inmsg_queue; updater_msgqueue_t inmsg_queue;
/*Current state of the updater one in code_states_e ENUM*/ /*Current state of the updater one in code_states_e ENUM*/
int* mode; int* mode;
uint8_t* update_no; uint8_t* update_no;
}; };
typedef struct buzz_updater_elem_s* buzz_updater_elem_t; typedef struct buzz_updater_elem_s* buzz_updater_elem_t;
/**************************************************************************/ /**************************************************************************/
/*Updater routine from msg processing to file checks to be called from main*/ /*Updater routine from msg processing to file checks to be called from main*/
/**************************************************************************/ /**************************************************************************/
void update_routine(); void update_routine();
/************************************************/ /************************************************/
/*Initalizes the updater */ /*Initalizes the updater */
/************************************************/ /************************************************/
int init_update_monitor(const char* bo_filename, const char* stand_by_script, const char* dbgfname, int robot_id); int init_update_monitor(const char* bo_filename, const char* stand_by_script, const char* dbgfname, int robot_id);
/*********************************************************/ /*********************************************************/
/*Appends buffer of given size to in msg queue of updater*/ /*Appends buffer of given size to in msg queue of updater*/
/*********************************************************/ /*********************************************************/
void code_message_inqueue_append(uint8_t* msg, uint16_t size); void code_message_inqueue_append(uint8_t* msg, uint16_t size);
/*********************************************************/ /*********************************************************/
/*Processes messages inside the queue of the updater*/ /*Processes messages inside the queue of the updater*/
/*********************************************************/ /*********************************************************/
void code_message_inqueue_process(); void code_message_inqueue_process();
/*****************************************************/ /*****************************************************/
/*Obtains messages from out msgs queue of the updater*/ /*Obtains messages from out msgs queue of the updater*/
/*******************************************************/ /*******************************************************/
uint8_t* getupdater_out_msg(); uint8_t* getupdater_out_msg();
/******************************************************/ /******************************************************/
/*Obtains out msg queue size*/ /*Obtains out msg queue size*/
/*****************************************************/ /*****************************************************/
uint8_t* getupdate_out_msg_size(); uint8_t* getupdate_out_msg_size();
/**************************************************/ /**************************************************/
/*Destroys the out msg queue*/ /*Destroys the out msg queue*/
/*************************************************/ /*************************************************/
void destroy_out_msg_queue(); void destroy_out_msg_queue();
// buzz_updater_elem_t get_updater(); // buzz_updater_elem_t get_updater();
/***************************************************/ /***************************************************/
/*Sets bzz file name*/ /*Sets bzz file name*/
/***************************************************/ /***************************************************/
void set_bzz_file(const char* in_bzz_file, bool dbg); void set_bzz_file(const char* in_bzz_file, bool dbg);
/****************************************************/ /****************************************************/
/*Tests the code from a buffer*/ /*Tests the code from a buffer*/
/***************************************************/ /***************************************************/
int test_set_code(uint8_t* BO_BUF, const char* dbgfname, size_t bcode_size); int test_set_code(uint8_t* BO_BUF, const char* dbgfname, size_t bcode_size);
/****************************************************/ /****************************************************/
/*Destroys the updater*/ /*Destroys the updater*/
/***************************************************/ /***************************************************/
void destroy_updater(); void destroy_updater();
/****************************************************/ /****************************************************/
/*Checks for updater message*/ /*Checks for updater message*/
/***************************************************/ /***************************************************/
int is_msg_present(); int is_msg_present();
/****************************************************/ /****************************************************/
/*Compiles a bzz script to bo and bdbg*/ /*Compiles a bzz script to bo and bdbg*/
/***************************************************/ /***************************************************/
int compile_bzz(std::string bzz_file); int compile_bzz(std::string bzz_file);
/****************************************************/ /****************************************************/
/*Set number of robots in the updater*/ /*Set number of robots in the updater*/
/***************************************************/ /***************************************************/
void updates_set_robots(int robots); void updates_set_robots(int robots);
} }
#endif #endif

View File

@ -53,8 +53,12 @@ struct neitime
double relative_rate; double relative_rate;
int age; int age;
neitime(uint64_t nht, uint64_t nlt, uint64_t mht, uint64_t mlt, double nr, double mr) neitime(uint64_t nht, uint64_t nlt, uint64_t mht, uint64_t mlt, double nr, double mr)
: nei_hardware_time(nht), nei_logical_time(nlt), node_hardware_time(mht), node_logical_time(mlt), : nei_hardware_time(nht)
nei_rate(nr), relative_rate(mr) {}; , nei_logical_time(nlt)
, node_hardware_time(mht)
, node_logical_time(mlt)
, nei_rate(nr)
, relative_rate(mr){};
neitime() neitime()
{ {
} }
@ -101,5 +105,4 @@ int get_inmsg_size();
std::vector<uint8_t*> get_inmsg_vector(); std::vector<uint8_t*> get_inmsg_vector();
std::string get_bvmstate(); std::string get_bvmstate();
} }

View File

@ -22,7 +22,7 @@ namespace buzzuav_closures
int buzzros_print(buzzvm_t vm); int buzzros_print(buzzvm_t vm);
void setWPlist(std::string file); void setWPlist(std::string file);
void setVorlog(std::string path); void setVorlog(std::string path);
void check_targets_sim(double lat, double lon, double *res); void check_targets_sim(double lat, double lon, double* res);
/* /*
* closure to move following a vector * closure to move following a vector
@ -98,7 +98,7 @@ double* getgoto();
/* /*
* returns the current grid * returns the current grid
*/ */
std::map<int, std::map<int,int>> getgrid(); std::map<int, std::map<int, int>> getgrid();
int voronoi_center(buzzvm_t vm); int voronoi_center(buzzvm_t vm);
/* /*

View File

@ -42,14 +42,14 @@
* ROSBuzz message types * ROSBuzz message types
*/ */
typedef enum { typedef enum {
ROS_BUZZ_MSG_NIL = 0, // dummy msg ROS_BUZZ_MSG_NIL = 0, // dummy msg
UPDATER_MESSAGE, // Update msg UPDATER_MESSAGE, // Update msg
BUZZ_MESSAGE, // Broadcast message BUZZ_MESSAGE, // Broadcast message
BUZZ_MESSAGE_TIME, // Broadcast message with time info BUZZ_MESSAGE_TIME, // Broadcast message with time info
} rosbuzz_msgtype; } rosbuzz_msgtype;
// Time sync algo. constants // Time sync algo. constants
#define COM_DELAY 100000000 // in nano seconds i.e 100 ms #define COM_DELAY 100000000 // in nano seconds i.e 100 ms
#define TIME_SYNC_JUMP_THR 500000000 #define TIME_SYNC_JUMP_THR 500000000
#define MOVING_AVERAGE_ALPHA 0.1 #define MOVING_AVERAGE_ALPHA 0.1
#define MAX_NUMBER_OF_ROBOTS 10 #define MAX_NUMBER_OF_ROBOTS 10
@ -107,8 +107,8 @@ private:
uint16_t size; uint16_t size;
uint64_t sent_time; uint64_t sent_time;
uint64_t received_time; uint64_t received_time;
MsgData(int mi, uint16_t ni, uint16_t s, uint64_t st, uint64_t rt): MsgData(int mi, uint16_t ni, uint16_t s, uint64_t st, uint64_t rt)
msgid(mi), nid(ni), size(s),sent_time(st), received_time(rt){}; : msgid(mi), nid(ni), size(s), sent_time(st), received_time(rt){};
MsgData(){}; MsgData(){};
}; };
typedef struct MsgData msg_data; typedef struct MsgData msg_data;

View File

@ -1,62 +1,43 @@
ROS Implemenation of Buzz ROSBuzz
========================= =========================
What is Buzz?
=============
Buzz is a novel programming language for heterogeneous robots swarms.
Buzz advocates a compositional approach, by offering primitives to define swarm behaviors both in a bottom-up and in a top-down fashion.
Bottom-up primitives include robot-wise commands and manipulation of neighborhood data through mapping/reducing/filtering operations.
Top-down primitives allow for the dynamic management of robot teams, and for sharing information globally across the swarm.
Self-organization results from the fact that the Buzz run-time platform is purely distributed.
The language can be extended to add new primitives (thus supporting heterogeneous robot swarms) and can be laid on top of other frameworks, such as ROS.
More information is available at http://the.swarming.buzz/wiki/doku.php?id=start.
Description: Description:
============ ============
Rosbuzz package is the ROS version of Buzz. The package contains a node called “rosbuzz_node”, which implements buzz virtual machine (BVM) as a node in ROS. ROSBuzz is a ROS node encompassing Buzz Virtual Machine (BVM) and interfacing with ROS ecosystem for mobile robots. The only node of the package is `rosbuzz_node`. It can be used in simulation-in-the-loop using Gazebo and was tested over many platforms (Clearpath Husky, DJI M100, Intel Aero, 3DR Solos, Pleidis Spiris, etc.). More information about ROSBuzz peripheral nodes is available in [1].
What is Buzz?
=============
Downloading ROS Package Buzz is a novel programming language for heterogeneous robots swarms. Buzz advocates a compositional approach, by offering primitives to define swarm behaviors both in a bottom-up and in a top-down fashion. Its official documentation and code are available [Buzz](https://github.com/MISTLab/Buzz).
=======================
$ git clone https://github.com/MISTLab/ROSBuzz.git rosbuzz
Requirements Requirements
============ ============
* Buzz : * Buzz:
You can download the development sources through git: Follow the required steps in [Buzz](https://github.com/MISTLab/ROSBuzz).
$ git clone https://github.com/MISTLab/Buzz.git buzz * ROS **base** binary distribution (Indigo or higher):
* ROS binary distribution (Indigo or higher) with catkin (could be used with older versions of ROS with catkin but not tested) Follow the required steps in [ROS Kinetic](https://wiki.ros.org/kinetic/Installation/Ubuntu). Note that the guidance and camera node of DJI for the M100 require to use the Indigo distribution.
* ROS additionnal dependencies:
You need the following package: ```
$ sudo apt-get install ros-<distro>-mavros ros-<distro>-mavros-extras
* mavros_msgs : ```
You can install using apt-get:
$ sudo apt-get install ros-<distro>-mavros ros-<distro>-mavros-extras
Compilation Compilation
=========== ===========
To compile the ros package, execute the following: ```
mkdir -p ROS_WS/src
$ cd catkin_ws cd ROS_WS/src
$ catkin_make git clone https://github.com/MISTLab/ROSBuzz rosbuzz
$ source devel/setup.bash cd ..
catkin_make
```
Run Run
=== ===
@ -64,42 +45,50 @@ To run the ROSBuzz package using the launch file, execute the following:
$ roslaunch rosbuzz rosbuzz.launch $ roslaunch rosbuzz rosbuzz.launch
Note : Before launching the ROSBuzz node, verify all the parameters in the launch file. A launch file using gdb is available also (rosbuzzd.launch). Have a look at the launch file to understand what parameters are available to suit your usage. All topics and services names are listed in `launch_config/topics.yaml`. Note : Before launching the ROSBuzz node, verify all the parameters in the launch file. A launch file using gdb is available too (rosbuzzd.launch).
* Buzz scripts: Several behavioral scripts are included in the "buzz_Scripts" folder, such as "graphformGPS.bzz" uses in the ICRA publication below and the "testaloneWP.bzz" to control a single drone with a ".csv" list of waypoints. The script "empty.bzz" is a template script. * Buzz scripts: Several behavioral scripts are included in the "buzz_Scripts" folder, such as "graphformGPS.bzz" uses in [1] and the "testaloneWP.bzz" to control a single drone with a ".csv" list of waypoints. The script "empty.bzz" is a template script.
Publisher Publishers
========= -----------
* Messages from Buzz (BVM): * Messages from Buzz (BVM):
The package publishes mavros_msgs/Mavlink message "outMavlink". The node publishes `mavros_msgs/Mavlink` message "outMavlink".
* Command to the flight controller: * Command to the flight controller:
The package publishes geometry_msgs/PoseStamped message "setpoint_position/local". The node publishes `geometry_msgs/PoseStamped message` "setpoint_position/local".
* Other information from the swarw:
The node publishes:
- "bvmstate" (`std_msgs/String`)
- "neighbours_pos" (`rosbuzz_msgs/neigh_pos`)
- "fleet_status" (`mavros_msgs/Mavlink`)
Subscribers Subscribers
----------- -----------
* Current position of the Robot: * Information from the Robot controller (mavros compliant):
The package subscribes to sensor_msgs/NavSatFix message "global_position/global", to a std_msgs/Float64 message "global_position/rel_alt" and to a geometry_msgs/PoseStamped message "local_position/pose". The node subscribes to:
- "global_position/global" (`sensor_msgs/NavSatFix message`)
- "global_position/rel_alt" (`std_msgs/Float64`)
- "local_position/pose" (`geometry_msgs/PoseStamped`)
- "battery" (`sensor_msgs/BatteryState`)
- either "extended_state" (`mavros_msgs/ExtendedState`) or "state" (`mavros_msgs/State`)
* Messages to Buzz (BVM): * Messages to Buzz (BVM):
The package subscribes to mavros_msgs/Mavlink message with a topic name of "inMavlink". The node subscribes to `mavros_msgs/Mavlink` incoming message with name "inMavlink".
* Status: Services
The package subscribes to mavros_msgs/BatteryStatus message "battery" and to either a mavros_msgs/ExtendedState message "extended_state" or a mavros_msgs/State message "state".
Service
------- -------
* Remote Controller: * Remote Controller:
The package offers a mavros_msgs/CommandLong service "buzzcmd" to control its state. In the "misc" folder a bash script shows how to control the Buzz states from the command line. The package offers a service "buzzcmd" (`mavros_msgs/CommandLong`) to control it. In the "misc" folder, a bash script shows how to control the swarm state from the command line.
References References
------ ------
* ROS and Buzz : consensus-based behaviors for heterogeneous teams. St-Onge, D., Shankar Varadharajan, V., Li, G., Svogor, I. and Beltrame, G. arXiv : https://arxiv.org/abs/1710.08843 * [1] ROS and Buzz : consensus-based behaviors for heterogeneous teams. St-Onge, D., Shankar Varadharajan, V., Li, G., Svogor, I. and Beltrame, G. arXiv : https://arxiv.org/abs/1710.08843
* Over-The-Air Updates for Robotic Swarms. Submitted to IEEE Software (August 2017). 8pgs. Shankar Varadharajan, V., St-Onge, D., Guß, C. and Beltrame, G. * [2] Over-The-Air Updates for Robotic Swarms. Submitted to IEEE Software (August 2017). 8pgs. Shankar Varadharajan, V., St-Onge, D., Guß, C. and Beltrame, G.
Visual Studio Code Visual Studio Code
-------------------- --------------------

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -17,7 +17,7 @@ static buzzvm_t VM = 0;
static char* BO_FNAME = 0; static char* BO_FNAME = 0;
static uint8_t* BO_BUF = 0; static uint8_t* BO_BUF = 0;
static buzzdebug_t DBG_INFO = 0; static buzzdebug_t DBG_INFO = 0;
static uint32_t MAX_MSG_SIZE = 190;//250; // Maximum Msg size for sending update packets static uint32_t MAX_MSG_SIZE = 190; // 250; // Maximum Msg size for sending update packets
static uint8_t Robot_id = 0; static uint8_t Robot_id = 0;
static std::vector<uint8_t*> IN_MSG; static std::vector<uint8_t*> IN_MSG;
std::map<int, Pos_struct> users_map; std::map<int, Pos_struct> users_map;
@ -572,7 +572,8 @@ int get_inmsg_size()
return IN_MSG.size(); return IN_MSG.size();
} }
std::vector<uint8_t*> get_inmsg_vector(){ std::vector<uint8_t*> get_inmsg_vector()
{
return IN_MSG; return IN_MSG;
} }
@ -590,11 +591,12 @@ string get_bvmstate()
---------------------------------------*/ ---------------------------------------*/
{ {
std::string uav_state = "Unknown"; std::string uav_state = "Unknown";
if(VM && VM->strings){ if (VM && VM->strings)
{
buzzvm_pushs(VM, buzzvm_string_register(VM, "BVMSTATE", 1)); buzzvm_pushs(VM, buzzvm_string_register(VM, "BVMSTATE", 1));
buzzvm_gload(VM); buzzvm_gload(VM);
buzzobj_t obj = buzzvm_stack_at(VM, 1); buzzobj_t obj = buzzvm_stack_at(VM, 1);
if(obj->o.type == BUZZTYPE_STRING) if (obj->o.type == BUZZTYPE_STRING)
uav_state = string(obj->s.value.str); uav_state = string(obj->s.value.str);
else else
uav_state = "Not Available"; uav_state = "Not Available";
@ -603,8 +605,8 @@ string get_bvmstate()
return uav_state; return uav_state;
} }
int get_swarmsize() { int get_swarmsize()
{
return (int)buzzdict_size(VM->swarmmembers) + 1; return (int)buzzdict_size(VM->swarmmembers) + 1;
} }
} }

View File

@ -42,11 +42,15 @@ static bool logVoronoi = false;
std::ofstream voronoicsv; std::ofstream voronoicsv;
struct Point struct Point
{ {
float x; float x;
float y; float y;
Point(): x( 0.0 ), y( 0.0 ) { } Point() : x(0.0), y(0.0)
Point( float x, float y ): x( x ), y( y ) { } {
}
Point(float x, float y) : x(x), y(y)
{
}
}; };
string WPlistname = ""; string WPlistname = "";
@ -54,7 +58,7 @@ std::map<int, buzz_utility::RB_struct> targets_map;
std::map<int, buzz_utility::RB_struct> wplist_map; std::map<int, buzz_utility::RB_struct> wplist_map;
std::map<int, buzz_utility::Pos_struct> neighbors_map; std::map<int, buzz_utility::Pos_struct> neighbors_map;
std::map<int, buzz_utility::neighbors_status> neighbors_status_map; std::map<int, buzz_utility::neighbors_status> neighbors_status_map;
std::map<int, std::map<int,int>> grid; std::map<int, std::map<int, int>> grid;
/****************************************/ /****************************************/
/****************************************/ /****************************************/
@ -123,7 +127,8 @@ void setVorlog(string path)
/ set the absolute path for a csv list of waypoints / set the absolute path for a csv list of waypoints
----------------------------------------------------------- */ ----------------------------------------------------------- */
{ {
voronoicsv.open(path + "/log/voronoi_"+std::to_string(buzz_utility::get_robotid())+".csv", std::ios_base::trunc | std::ios_base::out); voronoicsv.open(path + "/log/voronoi_" + std::to_string(buzz_utility::get_robotid()) + ".csv",
std::ios_base::trunc | std::ios_base::out);
logVoronoi = true; logVoronoi = true;
} }
@ -152,15 +157,18 @@ void rb_from_gps(double nei[], double out[], double cur[])
out[2] = 0.0; out[2] = 0.0;
} }
void gps_from_vec(double vec[], double gps[]) { void gps_from_vec(double vec[], double gps[])
{
double Vrange = sqrt(vec[0] * vec[0] + vec[1] * vec[1]); double Vrange = sqrt(vec[0] * vec[0] + vec[1] * vec[1]);
double Vbearing = constrainAngle(atan2(vec[1], vec[0])); double Vbearing = constrainAngle(atan2(vec[1], vec[0]));
double latR = cur_pos[0]*M_PI/180.0; double latR = cur_pos[0] * M_PI / 180.0;
double lonR = cur_pos[1]*M_PI/180.0; double lonR = cur_pos[1] * M_PI / 180.0;
double target_lat = asin(sin(latR) * cos(Vrange/EARTH_RADIUS) + cos(latR) * sin(Vrange/EARTH_RADIUS) * cos(Vbearing)); double target_lat =
double target_lon = lonR + atan2(sin(Vbearing) * sin(Vrange/EARTH_RADIUS) * cos(latR), cos(Vrange/EARTH_RADIUS) - sin(latR) * sin(target_lat)); asin(sin(latR) * cos(Vrange / EARTH_RADIUS) + cos(latR) * sin(Vrange / EARTH_RADIUS) * cos(Vbearing));
gps[0] = target_lat*180.0/M_PI; double target_lon = lonR + atan2(sin(Vbearing) * sin(Vrange / EARTH_RADIUS) * cos(latR),
gps[1] = target_lon*180.0/M_PI; cos(Vrange / EARTH_RADIUS) - sin(latR) * sin(target_lat));
gps[0] = target_lat * 180.0 / M_PI;
gps[1] = target_lon * 180.0 / M_PI;
gps[2] = cur_pos[2]; gps[2] = cur_pos[2];
} }
@ -215,7 +223,7 @@ void parse_gpslist()
fin.close(); fin.close();
} }
void check_targets_sim(double lat, double lon, double *res) void check_targets_sim(double lat, double lon, double* res)
/* /*
/ check if a listed target is close / check if a listed target is close
----------------------------------------------------------- */ ----------------------------------------------------------- */
@ -225,16 +233,19 @@ void check_targets_sim(double lat, double lon, double *res)
for (it = wplist_map.begin(); it != wplist_map.end(); ++it) for (it = wplist_map.begin(); it != wplist_map.end(); ++it)
{ {
double rb[3]; double rb[3];
double ref[2]={lat, lon}; double ref[2] = { lat, lon };
double tar[2]={it->second.latitude, it->second.longitude}; double tar[2] = { it->second.latitude, it->second.longitude };
rb_from_gps(tar, rb, ref); rb_from_gps(tar, rb, ref);
if(rb[0] < visibility_radius && (buzz_utility::get_bvmstate()=="WAYPOINT" && it->second.r==0)){ if (rb[0] < visibility_radius && (buzz_utility::get_bvmstate() == "WAYPOINT" && it->second.r == 0))
{
ROS_WARN("FOUND A TARGET IN WAYPOINT!!! [%i]", it->first); ROS_WARN("FOUND A TARGET IN WAYPOINT!!! [%i]", it->first);
res[0] = it->first; res[0] = it->first;
res[1] = it->second.latitude; res[1] = it->second.latitude;
res[2] = it->second.longitude; res[2] = it->second.longitude;
res[3] = it->second.altitude; res[3] = it->second.altitude;
} else if(rb[0] < visibility_radius && (buzz_utility::get_bvmstate()=="DEPLOY" && it->second.r==1)){ }
else if (rb[0] < visibility_radius && (buzz_utility::get_bvmstate() == "DEPLOY" && it->second.r == 1))
{
ROS_WARN("FOUND A TARGET IN WAYPOINT!!! [%i]", it->first); ROS_WARN("FOUND A TARGET IN WAYPOINT!!! [%i]", it->first);
res[0] = it->first; res[0] = it->first;
res[1] = it->second.latitude; res[1] = it->second.latitude;
@ -253,21 +264,23 @@ int buzz_exportmap(buzzvm_t vm)
buzzvm_lnum_assert(vm, 1); buzzvm_lnum_assert(vm, 1);
// Get the parameter // Get the parameter
buzzvm_lload(vm, 1); buzzvm_lload(vm, 1);
buzzvm_type_assert(vm, 1, BUZZTYPE_TABLE); // dictionary buzzvm_type_assert(vm, 1, BUZZTYPE_TABLE); // dictionary
buzzobj_t t = buzzvm_stack_at(vm, 1); buzzobj_t t = buzzvm_stack_at(vm, 1);
for(int32_t i = 1; i <= buzzdict_size(t->t.value); ++i) { for (int32_t i = 1; i <= buzzdict_size(t->t.value); ++i)
{
buzzvm_dup(vm); buzzvm_dup(vm);
buzzvm_pushi(vm, i); buzzvm_pushi(vm, i);
buzzvm_tget(vm); buzzvm_tget(vm);
std::map<int, int> row; std::map<int, int> row;
for(int32_t j = 1; j <= buzzdict_size(buzzvm_stack_at(vm, 1)->t.value); ++j) { for (int32_t j = 1; j <= buzzdict_size(buzzvm_stack_at(vm, 1)->t.value); ++j)
{
buzzvm_dup(vm); buzzvm_dup(vm);
buzzvm_pushi(vm, j); buzzvm_pushi(vm, j);
buzzvm_tget(vm); buzzvm_tget(vm);
row.insert(std::pair<int,int>(j, 100.0 - round(buzzvm_stack_at(vm, 1)->f.value*100.0))); row.insert(std::pair<int, int>(j, 100.0 - round(buzzvm_stack_at(vm, 1)->f.value * 100.0)));
buzzvm_pop(vm); buzzvm_pop(vm);
} }
grid.insert(std::pair<int,std::map<int, int>>(i,row)); grid.insert(std::pair<int, std::map<int, int>>(i, row));
buzzvm_pop(vm); buzzvm_pop(vm);
} }
// DEBUG // DEBUG
@ -277,252 +290,279 @@ int buzz_exportmap(buzzvm_t vm)
/* /*
* Geofence(): test for a point in a polygon * Geofence(): test for a point in a polygon
* TAKEN from https://www.geeksforgeeks.org/how-to-check-if-a-given-point-lies-inside-a-polygon/ * TAKEN from https://www.geeksforgeeks.org/how-to-check-if-a-given-point-lies-inside-a-polygon/
*/ */
// Given three colinear points p, q, r, the function checks if // Given three colinear points p, q, r, the function checks if
// point q lies on line segment 'pr' // point q lies on line segment 'pr'
bool onSegment(Point p, Point q, Point r) bool onSegment(Point p, Point q, Point r)
{
if (q.x <= max(p.x, r.x) && q.x >= min(p.x, r.x) &&
q.y <= max(p.y, r.y) && q.y >= min(p.y, r.y))
return true;
return false;
}
// To find orientation of ordered triplet (p, q, r).
// The function returns following values
// 0 --> p, q and r are colinear
// 1 --> Clockwise
// 2 --> Counterclockwise
int orientation(Point p, Point q, Point r)
{
int val =round((q.y - p.y) * (r.x - q.x)*100 -
(q.x - p.x) * (r.y - q.y)*100);
if (val == 0) return 0; // colinear
return (val > 0)? 1: 2; // clock or counterclock wise
}
// The function that returns true if line segment 'p1q1'
// and 'p2q2' intersect.
bool doIntersect(Point p1, Point q1, Point p2, Point q2)
{
// Find the four orientations needed for general and
// special cases
int o1 = orientation(p1, q1, p2);
int o2 = orientation(p1, q1, q2);
int o3 = orientation(p2, q2, p1);
int o4 = orientation(p2, q2, q1);
//ROS_WARN("(%f,%f)->(%f,%f), 1:%d,2:%d,3:%d,4:%d",p1.x,p1.y,q1.x,q1.y,o1,o2,o3,o4);
// General case
if (o1 != o2 && o3 != o4)
return true;
// Special Cases
// p1, q1 and p2 are colinear and p2 lies on segment p1q1
if (o1 == 0 && onSegment(p1, p2, q1)) return true;
// p1, q1 and p2 are colinear and q2 lies on segment p1q1
if (o2 == 0 && onSegment(p1, q2, q1)) return true;
// p2, q2 and p1 are colinear and p1 lies on segment p2q2
if (o3 == 0 && onSegment(p2, p1, q2)) return true;
// p2, q2 and q1 are colinear and q1 lies on segment p2q2
if (o4 == 0 && onSegment(p2, q1, q2)) return true;
return false; // Doesn't fall in any of the above cases
}
float clockwise_angle_of( const Point& p )
{ {
return atan2(p.y,p.x); if (q.x <= max(p.x, r.x) && q.x >= min(p.x, r.x) && q.y <= max(p.y, r.y) && q.y >= min(p.y, r.y))
return true;
return false;
} }
// To find orientation of ordered triplet (p, q, r).
bool clockwise_compare_points( const Point& a, const Point& b ) // The function returns following values
// 0 --> p, q and r are colinear
// 1 --> Clockwise
// 2 --> Counterclockwise
int orientation(Point p, Point q, Point r)
{ {
return clockwise_angle_of( a ) < clockwise_angle_of( b ); int val = round((q.y - p.y) * (r.x - q.x) * 100 - (q.x - p.x) * (r.y - q.y) * 100);
if (val == 0)
return 0; // colinear
return (val > 0) ? 1 : 2; // clock or counterclock wise
}
// The function that returns true if line segment 'p1q1'
// and 'p2q2' intersect.
bool doIntersect(Point p1, Point q1, Point p2, Point q2)
{
// Find the four orientations needed for general and
// special cases
int o1 = orientation(p1, q1, p2);
int o2 = orientation(p1, q1, q2);
int o3 = orientation(p2, q2, p1);
int o4 = orientation(p2, q2, q1);
// ROS_WARN("(%f,%f)->(%f,%f), 1:%d,2:%d,3:%d,4:%d",p1.x,p1.y,q1.x,q1.y,o1,o2,o3,o4);
// General case
if (o1 != o2 && o3 != o4)
return true;
// Special Cases
// p1, q1 and p2 are colinear and p2 lies on segment p1q1
if (o1 == 0 && onSegment(p1, p2, q1))
return true;
// p1, q1 and p2 are colinear and q2 lies on segment p1q1
if (o2 == 0 && onSegment(p1, q2, q1))
return true;
// p2, q2 and p1 are colinear and p1 lies on segment p2q2
if (o3 == 0 && onSegment(p2, p1, q2))
return true;
// p2, q2 and q1 are colinear and q1 lies on segment p2q2
if (o4 == 0 && onSegment(p2, q1, q2))
return true;
return false; // Doesn't fall in any of the above cases
} }
void sortclose_polygon(vector <Point> *P){ float clockwise_angle_of(const Point& p)
std::sort( P->begin(), P->end(), clockwise_compare_points ); {
return atan2(p.y, p.x);
}
bool clockwise_compare_points(const Point& a, const Point& b)
{
return clockwise_angle_of(a) < clockwise_angle_of(b);
}
void sortclose_polygon(vector<Point>* P)
{
std::sort(P->begin(), P->end(), clockwise_compare_points);
P->push_back((*P)[0]); P->push_back((*P)[0]);
} }
float pol_area(vector<Point> vert)
float pol_area(vector <Point> vert) { {
float a = 0.0; float a = 0.0;
//ROS_INFO("Polygone %d edges area.",vert.size()); // ROS_INFO("Polygone %d edges area.",vert.size());
vector <Point>::iterator it; vector<Point>::iterator it;
vector <Point>::iterator next; vector<Point>::iterator next;
for (it = vert.begin(); it != vert.end()-1; ++it){ for (it = vert.begin(); it != vert.end() - 1; ++it)
next = it+1; {
next = it + 1;
a += it->x * next->y - next->x * it->y; a += it->x * next->y - next->x * it->y;
} }
a *= 0.5; a *= 0.5;
//ROS_INFO("Polygon area: %f",a); // ROS_INFO("Polygon area: %f",a);
return a; return a;
} }
double* polygone_center(vector <Point> vert, double *c) { double* polygone_center(vector<Point> vert, double* c)
{
float A = pol_area(vert); float A = pol_area(vert);
int i1 = 1; int i1 = 1;
vector <Point>::iterator it; vector<Point>::iterator it;
vector <Point>::iterator next; vector<Point>::iterator next;
for (it = vert.begin(); it != vert.end()-1; ++it){ for (it = vert.begin(); it != vert.end() - 1; ++it)
next = it+1; {
float t = it->x*next->y - next->x*it->y; next = it + 1;
c[0] += (it->x+next->x) * t; float t = it->x * next->y - next->x * it->y;
c[1] += (it->y+next->y) * t; c[0] += (it->x + next->x) * t;
c[1] += (it->y + next->y) * t;
} }
c[0] = c[0] / (6.0 * A); c[0] = c[0] / (6.0 * A);
c[1] = c[1] / (6.0 * A); c[1] = c[1] / (6.0 * A);
return c; return c;
} }
double numerator ( Point A, Point C, Point E, Point F ) { return (A.y - C.y) * (F.x - E.x) - (A.x - C.x) * (F.y - E.y); } double numerator(Point A, Point C, Point E, Point F)
double denominator( Point A, Point B, Point C, Point D ) { return (B.x - A.x) * (D.y - C.y) - (B.y - A.y) * (D.x - C.x); } {
return (A.y - C.y) * (F.x - E.x) - (A.x - C.x) * (F.y - E.y);
}
double denominator(Point A, Point B, Point C, Point D)
{
return (B.x - A.x) * (D.y - C.y) - (B.y - A.y) * (D.x - C.x);
}
void getintersection(Point S, Point D, std::vector <Point> Poly, Point *I) { void getintersection(Point S, Point D, std::vector<Point> Poly, Point* I)
//printf("Points for intersection 1(%f,%f->%f,%f) and 2(%f,%f->%f,%f)\n",q1.x,q1.y,p1.x,p1.y,q2.x,q2.y,p2.x,p2.y); {
// printf("Points for intersection 1(%f,%f->%f,%f) and 2(%f,%f->%f,%f)\n",q1.x,q1.y,p1.x,p1.y,q2.x,q2.y,p2.x,p2.y);
bool parallel = false; bool parallel = false;
bool collinear = false; bool collinear = false;
std::vector <Point>::iterator itc; std::vector<Point>::iterator itc;
std::vector <Point>::iterator next; std::vector<Point>::iterator next;
for (itc = Poly.begin(); itc != Poly.end()-1; ++itc) { for (itc = Poly.begin(); itc != Poly.end() - 1; ++itc)
next = itc+1; {
if (doIntersect((*itc), (*next), S, D)) next = itc + 1;
if (doIntersect((*itc), (*next), S, D))
{ {
// Uses the determinant of the two lines. For more information, refer to one of the following: // Uses the determinant of the two lines. For more information, refer to one of the following:
// https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection#Given_two_points_on_each_line // https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection#Given_two_points_on_each_line
// http://www.faqs.org/faqs/graphics/algorithms-faq/ (Subject 1.03) // http://www.faqs.org/faqs/graphics/algorithms-faq/ (Subject 1.03)
double d = denominator( S, D, (*itc), (*next) ); double d = denominator(S, D, (*itc), (*next));
if (std::abs( d ) < 0.000000001) if (std::abs(d) < 0.000000001)
{ {
parallel = true; parallel = true;
collinear = abs(numerator( S, D, (*itc), (*next) )) < 0.000000001; collinear = abs(numerator(S, D, (*itc), (*next))) < 0.000000001;
return; return;
} }
double r = numerator( S, (*itc), (*itc), (*next) ) / d;
double s = numerator( S, (*itc), S, D ) / d;
//ROS_INFO("-- (%f,%f)",S.x + r * (D.x - S.x), S.y + r * (D.y - S.y)); double r = numerator(S, (*itc), (*itc), (*next)) / d;
(*I)=Point(S.x + r * (D.x - S.x), S.y + r * (D.y - S.y)); double s = numerator(S, (*itc), S, D) / d;
// ROS_INFO("-- (%f,%f)",S.x + r * (D.x - S.x), S.y + r * (D.y - S.y));
(*I) = Point(S.x + r * (D.x - S.x), S.y + r * (D.y - S.y));
} }
} }
if(parallel || collinear) if (parallel || collinear)
ROS_WARN("Lines are Collinear (%d) or Parallels (%d)",collinear,parallel); ROS_WARN("Lines are Collinear (%d) or Parallels (%d)", collinear, parallel);
} }
bool isSiteout(Point S, std::vector <Point> Poly) { bool isSiteout(Point S, std::vector<Point> Poly)
{
bool onedge = false; bool onedge = false;
// Create a point for line segment from p to infinite // Create a point for line segment from p to infinite
Point extreme = {10000, S.y}; Point extreme = { 10000, S.y };
// Count intersections of the above line with sides of polygon // Count intersections of the above line with sides of polygon
int count = 0; int count = 0;
std::vector <Point>::iterator itc; std::vector<Point>::iterator itc;
std::vector <Point>::iterator next; std::vector<Point>::iterator next;
for (itc = Poly.begin(); itc != Poly.end()-1; ++itc) { for (itc = Poly.begin(); itc != Poly.end() - 1; ++itc)
next = itc+1; {
next = itc + 1;
// Check if the line segment from 'p' to 'extreme' intersects // Check if the line segment from 'p' to 'extreme' intersects
// with the line segment from 'polygon[i]' to 'polygon[next]' // with the line segment from 'polygon[i]' to 'polygon[next]'
if (doIntersect((*itc), (*next), S, extreme)) if (doIntersect((*itc), (*next), S, extreme))
{ {
// If the point 'p' is colinear with line segment 'i-next', // If the point 'p' is colinear with line segment 'i-next',
// then check if it lies on segment. If it lies, return true, // then check if it lies on segment. If it lies, return true,
// otherwise false // otherwise false
if (orientation((*itc), S, (*next)) == 0) { if (orientation((*itc), S, (*next)) == 0)
onedge = onSegment((*itc), S, (*next)); {
if(onedge) onedge = onSegment((*itc), S, (*next));
break; if (onedge)
} break;
count++; }
count++;
} }
} }
return ((count%2 == 0) && !onedge); return ((count % 2 == 0) && !onedge);
} }
int buzzuav_geofence(buzzvm_t vm) int buzzuav_geofence(buzzvm_t vm)
{ {
Point P; Point P;
buzzvm_lnum_assert(vm, 1); buzzvm_lnum_assert(vm, 1);
// Get the parameter // Get the parameter
buzzvm_lload(vm, 1); buzzvm_lload(vm, 1);
buzzvm_type_assert(vm, 1, BUZZTYPE_TABLE); // dictionary buzzvm_type_assert(vm, 1, BUZZTYPE_TABLE); // dictionary
buzzobj_t t = buzzvm_stack_at(vm, 1); buzzobj_t t = buzzvm_stack_at(vm, 1);
if(buzzdict_size(t->t.value) < 5) { if (buzzdict_size(t->t.value) < 5)
ROS_ERROR("Wrong Geofence input size (%i).", buzzdict_size(t->t.value)); {
return buzzvm_ret0(vm); ROS_ERROR("Wrong Geofence input size (%i).", buzzdict_size(t->t.value));
return buzzvm_ret0(vm);
}
std::vector<Point> polygon_bound;
for (int32_t i = 0; i < buzzdict_size(t->t.value); ++i)
{
Point tmp;
buzzvm_dup(vm);
buzzvm_pushi(vm, i);
buzzvm_tget(vm);
buzzvm_dup(vm);
buzzvm_pushs(vm, buzzvm_string_register(vm, "x", 1));
buzzvm_tget(vm);
if (i == 0)
{
P.x = buzzvm_stack_at(vm, 1)->f.value;
// printf("px=%f\n",P.x);
} }
std::vector <Point> polygon_bound; else
for(int32_t i = 0; i < buzzdict_size(t->t.value); ++i) { {
Point tmp; tmp.x = buzzvm_stack_at(vm, 1)->f.value;
buzzvm_dup(vm); // printf("c%dx=%f\n",i,tmp.x);
buzzvm_pushi(vm, i);
buzzvm_tget(vm);
buzzvm_dup(vm);
buzzvm_pushs(vm, buzzvm_string_register(vm, "x", 1));
buzzvm_tget(vm);
if(i==0){
P.x = buzzvm_stack_at(vm, 1)->f.value;
//printf("px=%f\n",P.x);
}else{
tmp.x = buzzvm_stack_at(vm, 1)->f.value;
//printf("c%dx=%f\n",i,tmp.x);
}
buzzvm_pop(vm);
buzzvm_dup(vm);
buzzvm_pushs(vm, buzzvm_string_register(vm, "y", 1));
buzzvm_tget(vm);
//ROS_INFO("[%i]---y-->%i",buzz_utility::get_robotid(), tmp);
if(i==0){
P.y = buzzvm_stack_at(vm, 1)->f.value;
//printf("py=%f\n",P.y);
}else{
tmp.y = buzzvm_stack_at(vm, 1)->f.value;
//printf("c%dy=%f\n",i,tmp.y);
}
buzzvm_pop(vm);
if(i!=0)
polygon_bound.push_back(tmp);
buzzvm_pop(vm);
} }
sortclose_polygon(&polygon_bound); buzzvm_pop(vm);
buzzvm_dup(vm);
// Check if we are in the zone buzzvm_pushs(vm, buzzvm_string_register(vm, "y", 1));
if(isSiteout(P, polygon_bound)){ buzzvm_tget(vm);
Point Intersection; // ROS_INFO("[%i]---y-->%i",buzz_utility::get_robotid(), tmp);
getintersection(Point(0.0, 0.0) , P, polygon_bound, &Intersection); if (i == 0)
double gps[3]; {
double d[2]={Intersection.x,Intersection.y}; P.y = buzzvm_stack_at(vm, 1)->f.value;
gps_from_vec(d, gps); // printf("py=%f\n",P.y);
set_gpsgoal(gps);
ROS_WARN("Geofencing trigered, not going any further (%f,%f)!",d[0],d[1]);
} }
else
{
tmp.y = buzzvm_stack_at(vm, 1)->f.value;
// printf("c%dy=%f\n",i,tmp.y);
}
buzzvm_pop(vm);
if (i != 0)
polygon_bound.push_back(tmp);
buzzvm_pop(vm);
}
sortclose_polygon(&polygon_bound);
// Check if we are in the zone
if (isSiteout(P, polygon_bound))
{
Point Intersection;
getintersection(Point(0.0, 0.0), P, polygon_bound, &Intersection);
double gps[3];
double d[2] = { Intersection.x, Intersection.y };
gps_from_vec(d, gps);
set_gpsgoal(gps);
ROS_WARN("Geofencing trigered, not going any further (%f,%f)!", d[0], d[1]);
}
return buzzvm_ret0(vm); return buzzvm_ret0(vm);
} }
int voronoi_center(buzzvm_t vm) { int voronoi_center(buzzvm_t vm)
{
float dist_max = 300; float dist_max = 300;
buzzvm_lnum_assert(vm, 1); buzzvm_lnum_assert(vm, 1);
// Get the parameter // Get the parameter
buzzvm_lload(vm, 1); buzzvm_lload(vm, 1);
buzzvm_type_assert(vm, 1, BUZZTYPE_TABLE); // dictionary buzzvm_type_assert(vm, 1, BUZZTYPE_TABLE); // dictionary
buzzobj_t t = buzzvm_stack_at(vm, 1); buzzobj_t t = buzzvm_stack_at(vm, 1);
buzzvm_dup(vm); buzzvm_dup(vm);
@ -531,161 +571,191 @@ int voronoi_center(buzzvm_t vm) {
int Poly_vert = buzzvm_stack_at(vm, 1)->i.value; int Poly_vert = buzzvm_stack_at(vm, 1)->i.value;
buzzvm_pop(vm); buzzvm_pop(vm);
std::vector <Point> polygon_bound; std::vector<Point> polygon_bound;
for(int32_t i = 0; i < Poly_vert; ++i) { for (int32_t i = 0; i < Poly_vert; ++i)
{
buzzvm_dup(vm); buzzvm_dup(vm);
buzzvm_pushi(vm, i); buzzvm_pushi(vm, i);
buzzvm_tget(vm); buzzvm_tget(vm);
buzzvm_dup(vm); buzzvm_dup(vm);
buzzvm_pushs(vm, buzzvm_string_register(vm, "x", 1)); buzzvm_pushs(vm, buzzvm_string_register(vm, "x", 1));
buzzvm_tget(vm); buzzvm_tget(vm);
//ROS_INFO("---x-->%f",buzzvm_stack_at(vm, 1)->f.value); // ROS_INFO("---x-->%f",buzzvm_stack_at(vm, 1)->f.value);
float tmpx = buzzvm_stack_at(vm, 1)->f.value; float tmpx = buzzvm_stack_at(vm, 1)->f.value;
buzzvm_pop(vm); buzzvm_pop(vm);
buzzvm_dup(vm); buzzvm_dup(vm);
buzzvm_pushs(vm, buzzvm_string_register(vm, "y", 1)); buzzvm_pushs(vm, buzzvm_string_register(vm, "y", 1));
buzzvm_tget(vm); buzzvm_tget(vm);
//ROS_INFO("---y-->%f",buzzvm_stack_at(vm, 1)->f.value); // ROS_INFO("---y-->%f",buzzvm_stack_at(vm, 1)->f.value);
float tmpy = buzzvm_stack_at(vm, 1)->f.value; float tmpy = buzzvm_stack_at(vm, 1)->f.value;
buzzvm_pop(vm); buzzvm_pop(vm);
polygon_bound.push_back(Point(tmpx, tmpy)); polygon_bound.push_back(Point(tmpx, tmpy));
//ROS_INFO("[%i] Polygon vertex: %f, %f", buzz_utility::get_robotid(),tmpx,tmpy); // ROS_INFO("[%i] Polygon vertex: %f, %f", buzz_utility::get_robotid(),tmpx,tmpy);
buzzvm_pop(vm); buzzvm_pop(vm);
} }
sortclose_polygon(&polygon_bound); sortclose_polygon(&polygon_bound);
int count = buzzdict_size(t->t.value)-(Poly_vert+1);
ROS_WARN("NP: %d, Sites: %d", Poly_vert, count);
float *xValues = new float[count];
float *yValues = new float[count];
for(int32_t i = 0; i < count; ++i) {
int index = i + Poly_vert;
buzzvm_dup(vm);
buzzvm_pushi(vm, index);
buzzvm_tget(vm);
buzzvm_dup(vm);
buzzvm_pushs(vm, buzzvm_string_register(vm, "x", 1));
buzzvm_tget(vm);
//ROS_INFO("---x-->%f",buzzvm_stack_at(vm, 1)->f.value);
xValues[i] = buzzvm_stack_at(vm, 1)->f.value;
buzzvm_pop(vm);
buzzvm_dup(vm);
buzzvm_pushs(vm, buzzvm_string_register(vm, "y", 1));
buzzvm_tget(vm);
//ROS_INFO("---y-->%f",buzzvm_stack_at(vm, 1)->f.value);
yValues[i] = buzzvm_stack_at(vm, 1)->f.value;
buzzvm_pop(vm);
buzzvm_pop(vm); int count = buzzdict_size(t->t.value) - (Poly_vert + 1);
}
// Check if we are in the zone // Check if we are in the zone
if(isSiteout(Point(0,0), polygon_bound) || count < 3) { if (isSiteout(Point(0, 0), polygon_bound) || count < 3)
//ROS_WARN("Not in the Zone!!!"); {
// ROS_WARN("Not in the Zone!!!");
double goal_tmp[2]; double goal_tmp[2];
do{ do
goal_tmp[0] = polygon_bound[0].x + (rand()%100)/100.0*(polygon_bound[2].x- polygon_bound[0].x); {
goal_tmp[1] = polygon_bound[0].y + (rand()%100)/100.0*(polygon_bound[2].y- polygon_bound[0].y); goal_tmp[0] = polygon_bound[0].x + (rand() % 100) / 100.0 * (polygon_bound[2].x - polygon_bound[0].x);
//ROS_WARN(" in the Zone (%f,%f)!",goal_tmp[0],goal_tmp[1]); goal_tmp[1] = polygon_bound[0].y + (rand() % 100) / 100.0 * (polygon_bound[2].y - polygon_bound[0].y);
} while(isSiteout(Point(goal_tmp[0],goal_tmp[1]), polygon_bound)); // ROS_WARN(" in the Zone (%f,%f)!",goal_tmp[0],goal_tmp[1]);
ROS_WARN("Sending at a random location in the Zone (%f,%f)!",goal_tmp[0],goal_tmp[1]); } while (isSiteout(Point(goal_tmp[0], goal_tmp[1]), polygon_bound));
ROS_WARN("Sending at a random location in the Zone (%f,%f)!", goal_tmp[0], goal_tmp[1]);
double gps[3]; double gps[3];
gps_from_vec(goal_tmp, gps); gps_from_vec(goal_tmp, gps);
set_gpsgoal(gps); set_gpsgoal(gps);
return buzzvm_ret0(vm); return buzzvm_ret0(vm);
} }
VoronoiDiagramGenerator vdg;
ROS_WARN("[%i] Voronoi Bounded tessellation starting with %i sites...", buzz_utility::get_robotid(),count);
vdg.generateVoronoi(xValues, yValues, count, -dist_max, dist_max, -dist_max, dist_max, 3.0);
if(logVoronoi) voronoicsv << ros::Time::now().toNSec() << ",";
vdg.resetIterator();
//ROS_WARN("[%i] Voronoi Bounded tessellation done!", buzz_utility::get_robotid());
std::vector <Point>::iterator itc, next; ROS_WARN("NP: %d, Sites: %d", Poly_vert, count);
for (itc = polygon_bound.begin(); itc != polygon_bound.end()-1; ++itc) { float* xValues = new float[count];
next = itc+1; float* yValues = new float[count];
if(logVoronoi) voronoicsv << itc->x << "," << itc->y << "," << next->x << "," << next->y << "," << 0 << "," << 0 << ","; for (int32_t i = 0; i < count; ++i)
{
int index = i + Poly_vert;
buzzvm_dup(vm);
buzzvm_pushi(vm, index);
buzzvm_tget(vm);
buzzvm_dup(vm);
buzzvm_pushs(vm, buzzvm_string_register(vm, "x", 1));
buzzvm_tget(vm);
// ROS_INFO("---x-->%f",buzzvm_stack_at(vm, 1)->f.value);
xValues[i] = buzzvm_stack_at(vm, 1)->f.value;
buzzvm_pop(vm);
buzzvm_dup(vm);
buzzvm_pushs(vm, buzzvm_string_register(vm, "y", 1));
buzzvm_tget(vm);
// ROS_INFO("---y-->%f",buzzvm_stack_at(vm, 1)->f.value);
yValues[i] = buzzvm_stack_at(vm, 1)->f.value;
buzzvm_pop(vm);
buzzvm_pop(vm);
} }
float x1,y1,x2,y2; VoronoiDiagramGenerator vdg;
ROS_WARN("[%i] Voronoi Bounded tessellation starting with %i sites...", buzz_utility::get_robotid(), count);
vdg.generateVoronoi(xValues, yValues, count, -dist_max, dist_max, -dist_max, dist_max, 3.0);
if (logVoronoi)
voronoicsv << ros::Time::now().toNSec() << ",";
vdg.resetIterator();
// ROS_WARN("[%i] Voronoi Bounded tessellation done!", buzz_utility::get_robotid());
std::vector<Point>::iterator itc, next;
for (itc = polygon_bound.begin(); itc != polygon_bound.end() - 1; ++itc)
{
next = itc + 1;
if (logVoronoi)
voronoicsv << itc->x << "," << itc->y << "," << next->x << "," << next->y << "," << 0 << "," << 0 << ",";
}
float x1, y1, x2, y2;
int s[2]; int s[2];
vector <Point> cell_vert; vector<Point> cell_vert;
Point Intersection; Point Intersection;
int i=0; int i = 0;
while(vdg.getNext(x1,y1,x2,y2,s)) while (vdg.getNext(x1, y1, x2, y2, s))
{ {
//ROS_INFO("GOT Line (%f,%f)->(%f,%f) between sites %d,%d",x1,y1,x2,y2,s[0],s[1]); // ROS_INFO("GOT Line (%f,%f)->(%f,%f) between sites %d,%d",x1,y1,x2,y2,s[0],s[1]);
if(sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1))<0.1) if (sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)) < 0.1)
continue; continue;
bool isout1 = isSiteout(Point(x1,y1), polygon_bound); bool isout1 = isSiteout(Point(x1, y1), polygon_bound);
bool isout2 = isSiteout(Point(x2,y2), polygon_bound); bool isout2 = isSiteout(Point(x2, y2), polygon_bound);
if(isout1 && isout2){ if (isout1 && isout2)
//ROS_INFO("Line out of area!"); {
// ROS_INFO("Line out of area!");
continue; continue;
}else if(isout1) { }
getintersection(Point(x2,y2), Point(x1,y1), polygon_bound, &Intersection); else if (isout1)
{
getintersection(Point(x2, y2), Point(x1, y1), polygon_bound, &Intersection);
x1 = Intersection.x; x1 = Intersection.x;
y1 = Intersection.y; y1 = Intersection.y;
//ROS_INFO("Site out 1 -> (%f,%f)", x1, y1); // ROS_INFO("Site out 1 -> (%f,%f)", x1, y1);
}else if(isout2) { }
getintersection(Point(x1,y1), Point(x2,y2), polygon_bound, &Intersection); else if (isout2)
{
getintersection(Point(x1, y1), Point(x2, y2), polygon_bound, &Intersection);
x2 = Intersection.x; x2 = Intersection.x;
y2 = Intersection.y; y2 = Intersection.y;
//ROS_INFO("Site out 2 -> (%f,%f)", x2, y2); // ROS_INFO("Site out 2 -> (%f,%f)", x2, y2);
} }
if(logVoronoi) voronoicsv << x1 << "," << y1 << "," << x2 << "," << y2 << "," << s[0] << "," << s[1] << ","; if (logVoronoi)
voronoicsv << x1 << "," << y1 << "," << x2 << "," << y2 << "," << s[0] << "," << s[1] << ",";
i++; i++;
if((s[0]==0 || s[1]==0)) { if ((s[0] == 0 || s[1] == 0))
if(cell_vert.empty()){ {
cell_vert.push_back(Point(x1,y1)); if (cell_vert.empty())
cell_vert.push_back(Point(x2,y2)); {
} else { cell_vert.push_back(Point(x1, y1));
cell_vert.push_back(Point(x2, y2));
}
else
{
bool alreadyin = false; bool alreadyin = false;
vector <Point>::iterator itc; vector<Point>::iterator itc;
for (itc = cell_vert.begin(); itc != cell_vert.end(); ++itc) { for (itc = cell_vert.begin(); itc != cell_vert.end(); ++itc)
{
double dist = sqrt((itc->x - x1) * (itc->x - x1) + (itc->y - y1) * (itc->y - y1)); double dist = sqrt((itc->x - x1) * (itc->x - x1) + (itc->y - y1) * (itc->y - y1));
if(dist < 0.1) { if (dist < 0.1)
{
alreadyin = true; alreadyin = true;
break; break;
} }
} }
if(!alreadyin) if (!alreadyin)
cell_vert.push_back(Point(x1, y1)); cell_vert.push_back(Point(x1, y1));
alreadyin = false; alreadyin = false;
for (itc = cell_vert.begin(); itc != cell_vert.end(); ++itc) { for (itc = cell_vert.begin(); itc != cell_vert.end(); ++itc)
{
double dist = sqrt((itc->x - x2) * (itc->x - x2) + (itc->y - y2) * (itc->y - y2)); double dist = sqrt((itc->x - x2) * (itc->x - x2) + (itc->y - y2) * (itc->y - y2));
if(dist < 0.1) { if (dist < 0.1)
{
alreadyin = true; alreadyin = true;
break; break;
} }
} }
if(!alreadyin) if (!alreadyin)
cell_vert.push_back(Point(x2, y2)); cell_vert.push_back(Point(x2, y2));
} }
} }
} }
if(cell_vert.size()<3){ if (cell_vert.size() < 3)
ROS_WARN("[%i] Voronoi Bounded tessellation failed (%d)!", buzz_utility::get_robotid(),cell_vert.size()); {
ROS_WARN("[%i] Voronoi Bounded tessellation failed (%d)!", buzz_utility::get_robotid(), cell_vert.size());
delete xValues;
delete yValues;
return buzzvm_ret0(vm); return buzzvm_ret0(vm);
} }
std::sort( cell_vert.begin(), cell_vert.end(), clockwise_compare_points ); std::sort(cell_vert.begin(), cell_vert.end(), clockwise_compare_points);
cell_vert.push_back(cell_vert[0]); cell_vert.push_back(cell_vert[0]);
double center_dist[2] = {0.0, 0.0}; double center_dist[2] = { 0.0, 0.0 };
polygone_center(cell_vert, center_dist); polygone_center(cell_vert, center_dist);
if(logVoronoi) voronoicsv << center_dist[0] << "," << center_dist[1] << std::endl; if (logVoronoi)
center_dist[0]/=2; voronoicsv << center_dist[0] << "," << center_dist[1] << std::endl;
center_dist[1]/=2; center_dist[0] /= 2;
center_dist[1] /= 2;
double gps[3]; double gps[3];
gps_from_vec(center_dist, gps); gps_from_vec(center_dist, gps);
//ROS_INFO("[%i] Voronoi cell center: %f, %f, %f, %f", buzz_utility::get_robotid(), center_dist[0], center_dist[1], gps[0], gps[1]); // ROS_INFO("[%i] Voronoi cell center: %f, %f, %f, %f", buzz_utility::get_robotid(), center_dist[0], center_dist[1],
// gps[0], gps[1]);
set_gpsgoal(gps); set_gpsgoal(gps);
delete xValues;
delete yValues;
return buzzvm_ret0(vm); return buzzvm_ret0(vm);
} }
@ -769,7 +839,8 @@ int buzzuav_addNeiStatus(buzzvm_t vm)
buzzvm_lload(vm, 1); // state table buzzvm_lload(vm, 1); // state table
buzzvm_type_assert(vm, 1, BUZZTYPE_TABLE); buzzvm_type_assert(vm, 1, BUZZTYPE_TABLE);
buzzobj_t t = buzzvm_stack_at(vm, 1); buzzobj_t t = buzzvm_stack_at(vm, 1);
if(buzzdict_size(t->t.value) != 5) { if (buzzdict_size(t->t.value) != 5)
{
ROS_ERROR("Wrong neighbor status size."); ROS_ERROR("Wrong neighbor status size.");
return buzzvm_ret0(vm); return buzzvm_ret0(vm);
} }
@ -800,7 +871,7 @@ int buzzuav_addNeiStatus(buzzvm_t vm)
buzzvm_tget(vm); buzzvm_tget(vm);
newRS.flight_status = buzzvm_stack_at(vm, 1)->i.value; newRS.flight_status = buzzvm_stack_at(vm, 1)->i.value;
buzzvm_pop(vm); buzzvm_pop(vm);
map<int, buzz_utility::neighbors_status>::iterator it = neighbors_status_map.find(id); map<int, buzz_utility::neighbors_status>::iterator it = neighbors_status_map.find(id);
if (it != neighbors_status_map.end()) if (it != neighbors_status_map.end())
neighbors_status_map.erase(it); neighbors_status_map.erase(it);
@ -911,12 +982,17 @@ void set_gpsgoal(double goal[3])
{ {
double rb[3]; double rb[3];
rb_from_gps(goal, rb, cur_pos); rb_from_gps(goal, rb, cur_pos);
if (fabs(rb[0]) < 250.0) { if (fabs(rb[0]) < 250.0)
goto_gpsgoal[0] = goal[0];goto_gpsgoal[1] = goal[1];goto_gpsgoal[2] = goal[2]; {
ROS_INFO("[%i] Set GPS GOAL TO ---- %f %f %f (%f %f, %f %f)", buzz_utility::get_robotid(), goal[0], goal[1], goal[2], cur_pos[0], cur_pos[1], rb[0], rb[1]); goto_gpsgoal[0] = goal[0];
} else goto_gpsgoal[1] = goal[1];
ROS_WARN("[%i] GPS GOAL TOO FAR !!-- %f %f %f (%f %f, %f %f)", buzz_utility::get_robotid(), goal[0], goal[1], goal[2], cur_pos[0], cur_pos[1], rb[0], rb[1]); goto_gpsgoal[2] = goal[2];
ROS_INFO("[%i] Set GPS GOAL TO ---- %f %f %f (%f %f, %f %f)", buzz_utility::get_robotid(), goal[0], goal[1],
goal[2], cur_pos[0], cur_pos[1], rb[0], rb[1]);
}
else
ROS_WARN("[%i] GPS GOAL TOO FAR !!-- %f %f %f (%f %f, %f %f)", buzz_utility::get_robotid(), goal[0], goal[1],
goal[2], cur_pos[0], cur_pos[1], rb[0], rb[1]);
} }
int buzzuav_arm(buzzvm_t vm) int buzzuav_arm(buzzvm_t vm)
@ -987,7 +1063,7 @@ double* getgoto()
return goto_pos; return goto_pos;
} }
std::map<int, std::map<int,int>> getgrid() std::map<int, std::map<int, int>> getgrid()
/* /*
/ return the grid / return the grid
/-------------------------------------------------------------*/ /-------------------------------------------------------------*/
@ -1199,7 +1275,8 @@ void update_neighbors(buzzvm_t vm)
} }
// Clear neighbours pos // Clear neighbours pos
void clear_neighbours_pos(){ void clear_neighbours_pos()
{
neighbors_map.clear(); neighbors_map.clear();
} }

View File

@ -12,8 +12,8 @@ namespace rosbuzz_node
{ {
const string roscontroller::CAPTURE_SRV_DEFAULT_NAME = "/image_sender/capture_image"; const string roscontroller::CAPTURE_SRV_DEFAULT_NAME = "/image_sender/capture_image";
roscontroller::roscontroller(ros::NodeHandle& n_c, ros::NodeHandle& n_c_priv): roscontroller::roscontroller(ros::NodeHandle& n_c, ros::NodeHandle& n_c_priv)
logical_clock(ros::Time()), previous_step_time(ros::Time()) : logical_clock(ros::Time()), previous_step_time(ros::Time())
/* /*
/ roscontroller class Constructor / roscontroller class Constructor
---------------*/ ---------------*/
@ -26,7 +26,7 @@ logical_clock(ros::Time()), previous_step_time(ros::Time())
cur_pos.longitude = 0; cur_pos.longitude = 0;
cur_pos.latitude = 0; cur_pos.latitude = 0;
cur_pos.altitude = 0; cur_pos.altitude = 0;
// Obtain parameters from ros parameter server // Obtain parameters from ros parameter server
Rosparameters_get(n_c_priv); Rosparameters_get(n_c_priv);
// Initialize publishers, subscribers and client // Initialize publishers, subscribers and client
@ -35,9 +35,9 @@ logical_clock(ros::Time()), previous_step_time(ros::Time())
std::string fname = Compile_bzz(bzzfile_name); std::string fname = Compile_bzz(bzzfile_name);
bcfname = fname + ".bo"; bcfname = fname + ".bo";
dbgfname = fname + ".bdb"; dbgfname = fname + ".bdb";
buzz_update::set_bzz_file(bzzfile_name.c_str(),debug); buzz_update::set_bzz_file(bzzfile_name.c_str(), debug);
// Initialize variables // Initialize variables
if(setmode) if (setmode)
SetMode("LOITER", 0); SetMode("LOITER", 0);
goto_pos = buzzuav_closures::getgoto(); goto_pos = buzzuav_closures::getgoto();
@ -67,7 +67,7 @@ logical_clock(ros::Time()), previous_step_time(ros::Time())
logical_clock.fromSec(0); logical_clock.fromSec(0);
logical_time_rate = 0; logical_time_rate = 0;
time_sync_jumped = false; time_sync_jumped = false;
out_msg_time=0; out_msg_time = 0;
// Create log dir and open log file // Create log dir and open log file
initcsvlog(); initcsvlog();
buzzuav_closures::setWPlist(WPfile); buzzuav_closures::setWPlist(WPfile);
@ -126,7 +126,7 @@ void roscontroller::RosControllerRun()
// set ROS loop rate // set ROS loop rate
ros::Rate loop_rate(BUZZRATE); ros::Rate loop_rate(BUZZRATE);
// check for BVMSTATE variable // check for BVMSTATE variable
if(buzz_utility::get_bvmstate()=="Not Available") if (buzz_utility::get_bvmstate() == "Not Available")
ROS_ERROR("BVMSTATE undeclared in .bzz file, please set BVMSTATE."); ROS_ERROR("BVMSTATE undeclared in .bzz file, please set BVMSTATE.");
// DEBUG // DEBUG
// ROS_WARN("[%i] -----------------------STARTING MAIN LOOP!", robot_id); // ROS_WARN("[%i] -----------------------STARTING MAIN LOOP!", robot_id);
@ -138,7 +138,8 @@ void roscontroller::RosControllerRun()
grid_publisher(); grid_publisher();
send_MPpayload(); send_MPpayload();
// Check updater state and step code // Check updater state and step code
if(update) buzz_update::update_routine(); if (update)
buzz_update::update_routine();
if (time_step == BUZZRATE) if (time_step == BUZZRATE)
{ {
time_step = 0; time_step = 0;
@ -159,26 +160,29 @@ void roscontroller::RosControllerRun()
// log data // log data
logtocsv(); logtocsv();
// Call Step from buzz script // Call Step from buzz script
buzz_utility::buzz_script_step(); buzz_utility::buzz_script_step();
// Force a refresh on neighbors array once in a while // Force a refresh on neighbors array once in a while
if (timer_step >= 20*BUZZRATE){ if (timer_step >= 20 * BUZZRATE)
{
clear_pos(); clear_pos();
timer_step = 0; timer_step = 0;
} else }
else
timer_step++; timer_step++;
// Prepare messages and publish them // Prepare messages and publish them
prepare_msg_and_publish(); prepare_msg_and_publish();
// Call the flight controler service // Call the flight controler service
flight_controller_service_call(); flight_controller_service_call();
// Broadcast local position to FCU // Broadcast local position to FCU
if(BClpose && !setmode) if (BClpose && !setmode)
SetLocalPosition(goto_pos[0], goto_pos[1], goto_pos[2], goto_pos[3]); SetLocalPosition(goto_pos[0], goto_pos[1], goto_pos[2], goto_pos[3]);
// Set ROBOTS variable (swarm size) // Set ROBOTS variable (swarm size)
get_number_of_robots(); get_number_of_robots();
buzz_utility::set_robot_var(no_of_robots); buzz_utility::set_robot_var(no_of_robots);
if(update) buzz_update::updates_set_robots(no_of_robots); if (update)
buzz_update::updates_set_robots(no_of_robots);
// get_xbee_status(); // commented out because it may slow down the node too much, to be tested // get_xbee_status(); // commented out because it may slow down the node too much, to be tested
ros::spinOnce(); ros::spinOnce();
@ -203,19 +207,19 @@ void roscontroller::initcsvlog()
/ Create the CSV log file / Create the CSV log file
/-------------------------------------------------------*/ /-------------------------------------------------------*/
{ {
std::string path = std::string path = bzzfile_name.substr(0, bzzfile_name.find_last_of("\\/")) + "/";
bzzfile_name.substr(0, bzzfile_name.find_last_of("\\/")) + "/"; path = path.substr(0, bzzfile_name.find_last_of("\\/")) + "/log/";
path = path.substr(0, bzzfile_name.find_last_of("\\/"))+"/log/"; std::string folder_check = "mkdir -p " + path;
std::string folder_check="mkdir -p "+path;
system(folder_check.c_str()); system(folder_check.c_str());
for(int i=5;i>0;i--){ for (int i = 5; i > 0; i--)
rename((path +"logger_"+ std::to_string((uint8_t)robot_id)+"_"+std::to_string(i-1)+".log").c_str(), {
(path +"logger_"+ std::to_string((uint8_t)robot_id)+"_"+std::to_string(i)+".log").c_str()); rename((path + "logger_" + std::to_string((uint8_t)robot_id) + "_" + std::to_string(i - 1) + ".log").c_str(),
(path + "logger_" + std::to_string((uint8_t)robot_id) + "_" + std::to_string(i) + ".log").c_str());
} }
path += "logger_"+std::to_string(robot_id)+"_0.log"; path += "logger_" + std::to_string(robot_id) + "_0.log";
log.open(path.c_str(), std::ios_base::trunc | std::ios_base::out); log.open(path.c_str(), std::ios_base::trunc | std::ios_base::out);
// set log data double precision // set log data double precision
log <<std::setprecision(15) << std::fixed; log << std::setprecision(15) << std::fixed;
} }
void roscontroller::logtocsv() void roscontroller::logtocsv()
@ -225,28 +229,25 @@ void roscontroller::logtocsv()
{ {
// hardware time now // hardware time now
log << ros::Time::now().toNSec() << ","; log << ros::Time::now().toNSec() << ",";
log << cur_pos.latitude << "," << cur_pos.longitude << "," log << cur_pos.latitude << "," << cur_pos.longitude << "," << cur_pos.altitude << ",";
<< cur_pos.altitude << ",";
log << (int)no_of_robots << ","; log << (int)no_of_robots << ",";
log << neighbours_pos_map.size() << ","; log << neighbours_pos_map.size() << ",";
log << (int)inmsgdata.size() << "," << message_number << ","; log << (int)inmsgdata.size() << "," << message_number << ",";
log << out_msg_time <<","; log << out_msg_time << ",";
log << out_msg_size<<","; log << out_msg_size << ",";
log << buzz_utility::get_bvmstate(); log << buzz_utility::get_bvmstate();
map<int, buzz_utility::Pos_struct>::iterator it = map<int, buzz_utility::Pos_struct>::iterator it = neighbours_pos_map.begin();
neighbours_pos_map.begin();
for (; it != neighbours_pos_map.end(); ++it) for (; it != neighbours_pos_map.end(); ++it)
{ {
log << "," << it->first << ","; log << "," << it->first << ",";
log << (double)it->second.x << "," << (double)it->second.y log << (double)it->second.x << "," << (double)it->second.y << "," << (double)it->second.z;
<< "," << (double)it->second.z;
} }
for (std::vector<msg_data>::iterator it = inmsgdata.begin() ; it != inmsgdata.end(); ++it) for (std::vector<msg_data>::iterator it = inmsgdata.begin(); it != inmsgdata.end(); ++it)
{ {
log << "," << (int)it->nid << "," << (int)it->msgid << "," << (int)it->size << "," << log << "," << (int)it->nid << "," << (int)it->msgid << "," << (int)it->size << "," << it->sent_time << ","
it->sent_time << ","<< it->received_time; << it->received_time;
} }
inmsgdata.clear(); inmsgdata.clear();
log << std::endl; log << std::endl;
@ -395,7 +396,7 @@ void roscontroller::PubandServ(ros::NodeHandle& n_c, ros::NodeHandle& node_handl
} }
if (node_handle.getParam("services/modeclient", topic)) if (node_handle.getParam("services/modeclient", topic))
{ {
if(setmode) if (setmode)
mode_client = n_c.serviceClient<mavros_msgs::SetMode>(topic); mode_client = n_c.serviceClient<mavros_msgs::SetMode>(topic);
} }
else else
@ -480,11 +481,10 @@ void roscontroller::Initialize_pub_sub(ros::NodeHandle& n_c, ros::NodeHandle& n_
// Publishers and service Clients // Publishers and service Clients
PubandServ(n_c, n_c_priv); PubandServ(n_c, n_c_priv);
ROS_INFO("Ready to receive Mav Commands from RC client"); ROS_INFO("Ready to receive Mav Commands from RC client");
capture_srv = n_c.serviceClient<mavros_msgs::CommandBool>(capture_srv_name); capture_srv = n_c.serviceClient<mavros_msgs::CommandBool>(capture_srv_name);
multi_msg = true; multi_msg = true;
} }
@ -583,11 +583,12 @@ void roscontroller::neighbours_pos_publisher()
// cout<<"iterator it val: "<< it-> first << " After convertion: " // cout<<"iterator it val: "<< it-> first << " After convertion: "
// <<(uint8_t) buzz_utility::get_rid_uint8compac(it->first)<<endl; // <<(uint8_t) buzz_utility::get_rid_uint8compac(it->first)<<endl;
// std::cout<<"long obt"<<neigh_tmp.longitude<<endl; // std::cout<<"long obt"<<neigh_tmp.longitude<<endl;
// Check if any simulated target are in range // Check if any simulated target are in range
double tf[4] = {-1, 0, 0, 0}; double tf[4] = { -1, 0, 0, 0 };
buzzuav_closures::check_targets_sim((it->second).x, (it->second).y, tf); buzzuav_closures::check_targets_sim((it->second).x, (it->second).y, tf);
if(tf[0]!=-1){ if (tf[0] != -1)
{
buzz_utility::Pos_struct pos_tmp; buzz_utility::Pos_struct pos_tmp;
pos_tmp.x = tf[1]; pos_tmp.x = tf[1];
pos_tmp.y = tf[2]; pos_tmp.y = tf[2];
@ -641,24 +642,25 @@ void roscontroller::grid_publisher()
/ Publish current Grid from Buzz script / Publish current Grid from Buzz script
/----------------------------------------------------*/ /----------------------------------------------------*/
{ {
std::map<int, std::map<int,int>> grid = buzzuav_closures::getgrid(); std::map<int, std::map<int, int>> grid = buzzuav_closures::getgrid();
std::map<int, std::map<int,int>>::iterator itr = grid.begin(); std::map<int, std::map<int, int>>::iterator itr = grid.begin();
int g_w = itr->second.size(); int g_w = itr->second.size();
int g_h = grid.size(); int g_h = grid.size();
if(g_w!=0 && g_h!=0) { if (g_w != 0 && g_h != 0)
{
// DEBUG // DEBUG
//ROS_INFO("------> Publishing a grid of %i x %i", g_h, g_w); // ROS_INFO("------> Publishing a grid of %i x %i", g_h, g_w);
auto current_time = ros::Time::now(); auto current_time = ros::Time::now();
nav_msgs::OccupancyGrid grid_msg; nav_msgs::OccupancyGrid grid_msg;
grid_msg.header.frame_id = "/world"; grid_msg.header.frame_id = "/world";
grid_msg.header.stamp = current_time; grid_msg.header.stamp = current_time;
grid_msg.info.map_load_time = current_time; // Same as header stamp as we do not load the map. grid_msg.info.map_load_time = current_time; // Same as header stamp as we do not load the map.
grid_msg.info.resolution = 0.01;//gridMap.getResolution(); grid_msg.info.resolution = 0.01; // gridMap.getResolution();
grid_msg.info.width = g_w; grid_msg.info.width = g_w;
grid_msg.info.height = g_h; grid_msg.info.height = g_h;
grid_msg.info.origin.position.x = round(g_w/2.0) * grid_msg.info.resolution; grid_msg.info.origin.position.x = round(g_w / 2.0) * grid_msg.info.resolution;
grid_msg.info.origin.position.y = round(g_h/2.0) * grid_msg.info.resolution; grid_msg.info.origin.position.y = round(g_h / 2.0) * grid_msg.info.resolution;
grid_msg.info.origin.position.z = 0.0; grid_msg.info.origin.position.z = 0.0;
grid_msg.info.origin.orientation.x = 0.0; grid_msg.info.origin.orientation.x = 0.0;
grid_msg.info.origin.orientation.y = 0.0; grid_msg.info.origin.orientation.y = 0.0;
@ -666,19 +668,21 @@ void roscontroller::grid_publisher()
grid_msg.info.origin.orientation.w = 1.0; grid_msg.info.origin.orientation.w = 1.0;
grid_msg.data.resize(g_w * g_h); grid_msg.data.resize(g_w * g_h);
for (itr=grid.begin(); itr!=grid.end(); ++itr) { for (itr = grid.begin(); itr != grid.end(); ++itr)
std::map<int,int>::iterator itc = itr->second.begin(); {
for (itc=itr->second.begin(); itc!=itr->second.end(); ++itc) { std::map<int, int>::iterator itc = itr->second.begin();
grid_msg.data[(itr->first-1)*g_w+itc->first] = itc->second; for (itc = itr->second.begin(); itc != itr->second.end(); ++itc)
{
grid_msg.data[(itr->first - 1) * g_w + itc->first] = itc->second;
// DEBUG // DEBUG
//ROS_INFO("--------------> index: %i (%i,%i): %i", (itr->first-1)*g_w+itc->first, itr->first, itc->first, grid_msg.data[(itr->first-1)*g_w+itc->first]); // ROS_INFO("--------------> index: %i (%i,%i): %i", (itr->first-1)*g_w+itc->first, itr->first, itc->first,
// grid_msg.data[(itr->first-1)*g_w+itc->first]);
} }
} }
grid_pub.publish(grid_msg); grid_pub.publish(grid_msg);
} }
} }
void roscontroller::Arm() void roscontroller::Arm()
/* /*
/ Functions handling the local MAV ROS flight controller / Functions handling the local MAV ROS flight controller
@ -729,13 +733,13 @@ with size......... | /
else else
message_number++; message_number++;
//header variables // header variables
uint16_t tmphead[4]; uint16_t tmphead[4];
tmphead[1] = (uint16_t)message_number; tmphead[1] = (uint16_t)message_number;
//uint32_t stime = (uint32_t)(ros::Time::now().toSec()); //(uint32_t)(logical_clock.toSec() * 100000); // uint32_t stime = (uint32_t)(ros::Time::now().toSec()); //(uint32_t)(logical_clock.toSec() * 100000);
memcpy((void*)(tmphead+2),(void*)&stime,sizeof(uint32_t)); memcpy((void*)(tmphead + 2), (void*)&stime, sizeof(uint32_t));
uint64_t rheader[1]; uint64_t rheader[1];
rheader[0]=0; rheader[0] = 0;
payload_out.sysid = (uint8_t)robot_id; payload_out.sysid = (uint8_t)robot_id;
payload_out.msgid = (uint32_t)message_number; payload_out.msgid = (uint32_t)message_number;
@ -755,7 +759,7 @@ with size......... | /
{ {
payload_out.payload64.push_back(payload_out_ptr[i]); payload_out.payload64.push_back(payload_out_ptr[i]);
} }
//Store out msg time // Store out msg time
out_msg_time = ros::Time::now().toNSec(); out_msg_time = ros::Time::now().toNSec();
out_msg_size = out[0]; out_msg_size = out[0];
// publish prepared messages in respective topic // publish prepared messages in respective topic
@ -825,7 +829,8 @@ script
cmd_srv.request.command = buzzuav_closures::getcmd(); cmd_srv.request.command = buzzuav_closures::getcmd();
if (!armstate) if (!armstate)
{ {
if(setmode){ if (setmode)
{
SetMode("LOITER", 0); SetMode("LOITER", 0);
ros::Duration(0.5).sleep(); ros::Duration(0.5).sleep();
} }
@ -834,13 +839,13 @@ script
// Registering HOME POINT. // Registering HOME POINT.
home = cur_pos; home = cur_pos;
// Initialize GPS goal for safety. // Initialize GPS goal for safety.
double gpspgoal[3] = {cur_pos.latitude,cur_pos.longitude,cur_pos.altitude}; double gpspgoal[3] = { cur_pos.latitude, cur_pos.longitude, cur_pos.altitude };
buzzuav_closures::set_gpsgoal(gpspgoal); buzzuav_closures::set_gpsgoal(gpspgoal);
BClpose = true; BClpose = true;
} }
if (current_mode != "GUIDED" && setmode) if (current_mode != "GUIDED" && setmode)
SetMode("GUIDED", 3000); // added for compatibility with 3DR Solo SetMode("GUIDED", 3000); // added for compatibility with 3DR Solo
if(setmode) if (setmode)
{ {
if (mav_client.call(cmd_srv)) if (mav_client.call(cmd_srv))
{ {
@ -862,7 +867,7 @@ script
armstate = 0; armstate = 0;
Arm(); Arm();
} }
else if(cur_pos.altitude < 0.4) //disarm only when close to ground else if (cur_pos.altitude < 0.4) // disarm only when close to ground
{ {
armstate = 0; armstate = 0;
Arm(); Arm();
@ -894,17 +899,17 @@ script
case COMPONENT_ARM_DISARM: case COMPONENT_ARM_DISARM:
if (!armstate) if (!armstate)
{ {
if(setmode) if (setmode)
SetMode("LOITER", 0); SetMode("LOITER", 0);
armstate = 1; armstate = 1;
Arm(); Arm();
} }
break; break;
case COMPONENT_ARM_DISARM+1: case COMPONENT_ARM_DISARM + 1:
if (armstate) if (armstate)
{ {
if(setmode) if (setmode)
SetMode("LOITER", 0); SetMode("LOITER", 0);
armstate = 0; armstate = 0;
Arm(); Arm();
@ -913,7 +918,7 @@ script
case NAV_SPLINE_WAYPOINT: case NAV_SPLINE_WAYPOINT:
goto_pos = buzzuav_closures::getgoto(); goto_pos = buzzuav_closures::getgoto();
if(setmode) if (setmode)
SetLocalPosition(goto_pos[0], goto_pos[1], goto_pos[2], goto_pos[3]); SetLocalPosition(goto_pos[0], goto_pos[1], goto_pos[2], goto_pos[3]);
break; break;
@ -950,12 +955,11 @@ void roscontroller::clear_pos()
/Refresh neighbours Position for every ten step /Refresh neighbours Position for every ten step
/---------------------------------------------*/ /---------------------------------------------*/
{ {
neighbours_pos_map.clear();
neighbours_pos_map.clear(); raw_neighbours_pos_map.clear();
raw_neighbours_pos_map.clear(); buzzuav_closures::clear_neighbours_pos();
buzzuav_closures::clear_neighbours_pos(); // raw_neighbours_pos_map.clear(); // TODO: currently not a problem, but
// raw_neighbours_pos_map.clear(); // TODO: currently not a problem, but // have to clear !
// have to clear !
} }
void roscontroller::neighbours_pos_put(int id, buzz_utility::Pos_struct pos_arr) void roscontroller::neighbours_pos_put(int id, buzz_utility::Pos_struct pos_arr)
@ -1088,21 +1092,17 @@ void roscontroller::local_pos_callback(const geometry_msgs::PoseStamped::ConstPt
cur_pos.x = msg->pose.position.x; cur_pos.x = msg->pose.position.x;
cur_pos.y = msg->pose.position.y; cur_pos.y = msg->pose.position.y;
if(!BClpose) if (!BClpose)
{ {
goto_pos[0]=cur_pos.x; goto_pos[0] = cur_pos.x;
goto_pos[1]=cur_pos.y; goto_pos[1] = cur_pos.y;
goto_pos[2]=0.0; goto_pos[2] = 0.0;
BClpose = true; BClpose = true;
} }
buzzuav_closures::set_currentNEDpos(msg->pose.position.y,msg->pose.position.x); buzzuav_closures::set_currentNEDpos(msg->pose.position.y, msg->pose.position.x);
// cur_pos.z = pose->pose.position.z; // Using relative altitude topic instead // cur_pos.z = pose->pose.position.z; // Using relative altitude topic instead
tf::Quaternion q( tf::Quaternion q(msg->pose.orientation.x, msg->pose.orientation.y, msg->pose.orientation.z, msg->pose.orientation.w);
msg->pose.orientation.x,
msg->pose.orientation.y,
msg->pose.orientation.z,
msg->pose.orientation.w);
tf::Matrix3x3 m(q); tf::Matrix3x3 m(q);
double roll, pitch, yaw; double roll, pitch, yaw;
m.getRPY(roll, pitch, yaw); m.getRPY(roll, pitch, yaw);
@ -1157,8 +1157,8 @@ void roscontroller::SetLocalPosition(float x, float y, float z, float yaw)
moveMsg.pose.orientation.w = q[3]; moveMsg.pose.orientation.w = q[3];
// To prevent drifting from stable position, uncomment // To prevent drifting from stable position, uncomment
//if(fabs(x)>0.005 || fabs(y)>0.005) { // if(fabs(x)>0.005 || fabs(y)>0.005) {
localsetpoint_nonraw_pub.publish(moveMsg); localsetpoint_nonraw_pub.publish(moveMsg);
//} //}
} }
@ -1197,15 +1197,15 @@ void roscontroller::SetStreamRate(int id, int rate, int on_off)
message.request.stream_id = id; message.request.stream_id = id;
message.request.message_rate = rate; message.request.message_rate = rate;
message.request.on_off = on_off; message.request.on_off = on_off;
int timeout = 20; // 2sec at 10Hz int timeout = 20; // 2sec at 10Hz
while (!stream_client.call(message) && timeout>0) while (!stream_client.call(message) && timeout > 0)
{ {
ROS_INFO("Set stream rate call failed!, trying again..."); ROS_INFO("Set stream rate call failed!, trying again...");
ros::Duration(0.1).sleep(); ros::Duration(0.1).sleep();
timeout--; timeout--;
} }
if(timeout<1) if (timeout < 1)
ROS_ERROR("Set stream rate timed out!"); ROS_ERROR("Set stream rate timed out!");
else else
ROS_WARN("Set stream rate call successful"); ROS_WARN("Set stream rate call successful");
@ -1228,12 +1228,12 @@ void roscontroller::payload_obt(const mavros_msgs::Mavlink::ConstPtr& msg)
// decode msg header // decode msg header
uint64_t rhead = msg->payload64[0]; uint64_t rhead = msg->payload64[0];
uint16_t r16head[4]; uint16_t r16head[4];
memcpy(r16head,&rhead, sizeof(uint64_t)); memcpy(r16head, &rhead, sizeof(uint64_t));
uint16_t mtype = r16head[0]; uint16_t mtype = r16head[0];
uint16_t mid = r16head[1]; uint16_t mid = r16head[1];
uint32_t temptime=0; uint32_t temptime = 0;
memcpy(&temptime, r16head+2, sizeof(uint32_t)); memcpy(&temptime, r16head + 2, sizeof(uint32_t));
//float stime = (float)temptime/(float)100000; // float stime = (float)temptime/(float)100000;
// if(debug) ROS_INFO("Received Msg: sent time %f for id %u",stime, mid); // if(debug) ROS_INFO("Received Msg: sent time %f for id %u",stime, mid);
// Check for Updater message, if updater message push it into updater FIFO // Check for Updater message, if updater message push it into updater FIFO
if ((uint64_t)msg->payload64[0] == (uint64_t)UPDATER_MESSAGE) if ((uint64_t)msg->payload64[0] == (uint64_t)UPDATER_MESSAGE)
@ -1284,7 +1284,7 @@ void roscontroller::payload_obt(const mavros_msgs::Mavlink::ConstPtr& msg)
// Extract robot id of the neighbour // Extract robot id of the neighbour
uint16_t* out = buzz_utility::u64_cvt_u16((uint64_t) * (message_obt + index)); uint16_t* out = buzz_utility::u64_cvt_u16((uint64_t) * (message_obt + index));
// store in msg data for data log // store in msg data for data log
msg_data inm(mid,out[1],out[0]*sizeof(uint64_t),stime,ros::Time::now().toNSec()); msg_data inm(mid, out[1], out[0] * sizeof(uint64_t), stime, ros::Time::now().toNSec());
inmsgdata.push_back(inm); inmsgdata.push_back(inm);
if (debug) if (debug)