update rosbuzz repo

This commit is contained in:
David St-Onge 2017-11-28 13:22:29 -05:00
commit 369006413f
41 changed files with 3383 additions and 1725 deletions

1
.gitignore vendored
View File

@ -5,3 +5,4 @@ src/test*
*.bo *.bo
*.bdb *.bdb
*.bdbg *.bdbg
buzz_scripts/log*

17
buzz_scripts/empty.bzz Normal file
View File

@ -0,0 +1,17 @@
include "update.bzz"
# Executed once at init time.
function init() {
}
# Executed at each time step.
function step() {
}
# Executed once when the robot (or the simulator) is reset.
function reset() {
}
# Executed once at the end of experiment.
function destroy() {
}

View File

@ -38,7 +38,7 @@ function action() {
# Move according to vector # Move according to vector
print("Robot ", id, "must push ", math.vec2.length(accum) )#, "; ", math.vec2.angle(accum)) print("Robot ", id, "must push ", math.vec2.length(accum) )#, "; ", math.vec2.angle(accum))
uav_moveto(accum.x, accum.y) uav_moveto(accum.x, accum.y, 0.0)
UAVSTATE = "LENNARDJONES" UAVSTATE = "LENNARDJONES"
# if(timeW>=WAIT_TIMEOUT) { #FOR MOVETO TESTS # if(timeW>=WAIT_TIMEOUT) { #FOR MOVETO TESTS
@ -47,11 +47,11 @@ function action() {
# } else if(timeW>=WAIT_TIMEOUT/2) { # } else if(timeW>=WAIT_TIMEOUT/2) {
# UAVSTATE ="GOEAST" # UAVSTATE ="GOEAST"
# timeW = timeW+1 # timeW = timeW+1
# uav_moveto(0.0,5.0) # uav_moveto(0.0, 5.0, 0.0)
# } else { # } else {
# UAVSTATE ="GONORTH" # UAVSTATE ="GONORTH"
# timeW = timeW+1 # timeW = timeW+1
# uav_moveto(5.0,0.0) # uav_moveto(5.0, 0.0, 0.0)
# } # }
} }
@ -65,15 +65,19 @@ function action() {
function init() { function init() {
uav_initswarm() uav_initswarm()
uav_initstig() uav_initstig()
# TARGET_ALTITUDE = 2.5 + id * 5
statef=turnedoff
UAVSTATE = "TURNEDOFF"
} }
# Executed at each time step. # Executed at each time step.
function step() { function step() {
uav_rccmd() uav_rccmd()
uav_neicmd() uav_neicmd()
uav_updatestig()
statef() statef()
uav_updatestig()
log("Current state: ", UAVSTATE) log("Current state: ", UAVSTATE)
log("Swarm size: ",ROBOTS) log("Swarm size: ",ROBOTS)
if(id==0) if(id==0)

View File

@ -4,18 +4,20 @@
include "string.bzz" include "string.bzz"
include "vec2.bzz" include "vec2.bzz"
include "update.bzz" include "update.bzz"
include "barrier.bzz" # don't use a stigmergy id=11 with this header.
include "vstigenv.bzz" # reserve stigmergy id=20 and 21 for this header.
include "barrier.bzz" # reserve stigmergy id=11 for this header.
include "uavstates.bzz" # require an 'action' function to be defined here. include "uavstates.bzz" # require an 'action' function to be defined here.
include "vstigenv.bzz"
include "graphs/shapes_Y.bzz" include "graphs/shapes_Y.bzz"
ROBOT_RADIUS=50 ROBOT_RADIUS = 50
ROBOT_DIAMETER=2.0*ROBOT_RADIUS ROBOT_DIAMETER = 2.0*ROBOT_RADIUS
ROBOT_SAFETYDIST=2.0*ROBOT_DIAMETER ROBOT_SAFETYDIST = 2.0*ROBOT_DIAMETER
ROOT_ID = 2
# max velocity in cm/step # max velocity in cm/step
ROBOT_MAXVEL = 250.0 ROBOT_MAXVEL = 150.0
# #
# Global variables # Global variables
@ -42,7 +44,7 @@ m_receivedMessage={.State=s2i("STATE_FREE"),.Label=0,.ReqLabel=0,.ReqID=0,.Respo
m_selfMessage={.State=s2i("STATE_FREE"),.Label=0,.ReqLabel=0,.ReqID=0,.Response=r2i("REQ_NONE")} m_selfMessage={.State=s2i("STATE_FREE"),.Label=0,.ReqLabel=0,.ReqID=0,.Response=r2i("REQ_NONE")}
#Current robot state #Current robot state
m_eState="STATE_FREE" # m_eState="STATE_FREE" # replace with default UAVSTATE
#navigation vector #navigation vector
m_navigation={.x=0,.y=0} m_navigation={.x=0,.y=0}
@ -87,11 +89,11 @@ m_fTargetDistanceTolerance=0
#step cunt #step cunt
step_cunt=0 step_cunt=0
#virtual stigmergy # virtual stigmergy for the LOCK barrier.
m_lockstig = 1 m_lockstig = 1
# Lennard-Jones parameters, may need change # Lennard-Jones parameters, may need change
EPSILON = 4000 #13.5 the LJ parameter for other robots EPSILON = 1800 #13.5 the LJ parameter for other robots
# Lennard-Jones interaction magnitude # Lennard-Jones interaction magnitude
@ -100,24 +102,6 @@ function FlockInteraction(dist,target,epsilon){
return mag return mag
} }
function LimitAngle(angle){
if(angle>2*math.pi)
return angle-2*math.pi
else if (angle<0)
return angle+2*math.pi
else
return angle
}
#
# Calculates the angle of the given vector2.
# PARAM v: The vector2.
# RETURN: The angle of the vector.
#
Angle = function(v) {
return math.atan(v.y, v.x)
}
# #
#return the number of value in table #return the number of value in table
# #
@ -204,26 +188,12 @@ function find(table,value){
return index return index
} }
function pow(base,exponent){
var i=0
var renturn_val=1
if(exponent==0)
return 1
else{
while(i<exponent){
renturn_val=renturn_val*base
i=i+1
}
return renturn_val
}
}
# #
#pack message into 1 number #pack message into 1 number
# #
function packmessage(send_table){ function packmessage(send_table){
var send_value var send_value
send_value=10000*send_table.State+1000*send_table.Label+100*send_table.ReqLabel+10*send_table.ReqID+send_table.Response send_value=100000*send_table.State+10000*send_table.Label+1000*send_table.ReqLabel+10*send_table.ReqID+send_table.Response
return send_value return send_value
} }
# #
@ -247,12 +217,12 @@ function pack_guide_msg(send_table){
#unpack message #unpack message
# #
function unpackmessage(recv_value){ function unpackmessage(recv_value){
var wan=(recv_value-recv_value%10000)/10000 var wan=(recv_value-recv_value%100000)/100000
recv_value=recv_value-wan*10000 recv_value=recv_value-wan*100000
var qian=(recv_value-recv_value%1000)/1000 var qian=(recv_value-recv_value%10000)/10000
recv_value=recv_value-qian*1000 recv_value=recv_value-qian*10000
var bai=(recv_value-recv_value%100)/100 var bai=(recv_value-recv_value%1000)/1000
recv_value=recv_value-bai*100 recv_value=recv_value-bai*1000
var shi=(recv_value-recv_value%10)/10 var shi=(recv_value-recv_value%10)/10
recv_value=recv_value-shi*10 recv_value=recv_value-shi*10
var ge=recv_value var ge=recv_value
@ -391,19 +361,19 @@ function UpdateNodeInfo(){
#Transistion to state free #Transistion to state free
# #
function TransitionToFree(){ function TransitionToFree(){
m_eState="STATE_FREE" UAVSTATE="STATE_FREE"
m_unWaitCount=m_unLabelSearchWaitTime m_unWaitCount=m_unLabelSearchWaitTime
m_selfMessage.State=s2i(m_eState) m_selfMessage.State=s2i(UAVSTATE)
} }
# #
#Transistion to state asking #Transistion to state asking
# #
function TransitionToAsking(un_label){ function TransitionToAsking(un_label){
m_eState="STATE_ASKING" UAVSTATE="STATE_ASKING"
m_nLabel=un_label m_nLabel=un_label
m_unRequestId=id #don't know why the random numbers are the same, add id to make the ReqID different m_unRequestId=id #don't know why the random numbers are the same, add id to make the ReqID different
m_selfMessage.State=s2i(m_eState) m_selfMessage.State=s2i(UAVSTATE)
m_selfMessage.ReqLabel=m_nLabel m_selfMessage.ReqLabel=m_nLabel
m_selfMessage.ReqID=m_unRequestId m_selfMessage.ReqID=m_unRequestId
@ -414,8 +384,8 @@ function TransitionToAsking(un_label){
#Transistion to state joining #Transistion to state joining
# #
function TransitionToJoining(){ function TransitionToJoining(){
m_eState="STATE_JOINING" UAVSTATE="STATE_JOINING"
m_selfMessage.State=s2i(m_eState) m_selfMessage.State=s2i(UAVSTATE)
m_selfMessage.Label=m_nLabel m_selfMessage.Label=m_nLabel
m_unWaitCount=m_unJoiningLostPeriod m_unWaitCount=m_unJoiningLostPeriod
@ -435,8 +405,8 @@ function TransitionToJoining(){
#Transistion to state joined #Transistion to state joined
# #
function TransitionToJoined(){ function TransitionToJoined(){
m_eState="STATE_JOINED" UAVSTATE="STATE_JOINED"
m_selfMessage.State=s2i(m_eState) m_selfMessage.State=s2i(UAVSTATE)
m_selfMessage.Label=m_nLabel m_selfMessage.Label=m_nLabel
m_vecNodes[m_nLabel].State="ASSIGNED" m_vecNodes[m_nLabel].State="ASSIGNED"
neighbors.ignore("r") neighbors.ignore("r")
@ -446,7 +416,7 @@ function TransitionToJoined(){
m_navigation.x=0.0 m_navigation.x=0.0
m_navigation.y=0.0 m_navigation.y=0.0
uav_moveto(m_navigation.x/100.0,m_navigation.y/100.0) uav_moveto(m_navigation.x/100.0, m_navigation.y/100.0, 0.0)
} }
# #
@ -456,8 +426,8 @@ function TransitionToJoined(){
#Transistion to state Lock, lock the current formation #Transistion to state Lock, lock the current formation
# #
function TransitionToLock(){ function TransitionToLock(){
m_eState="STATE_LOCK" UAVSTATE="STATE_LOCK"
m_selfMessage.State=s2i(m_eState) m_selfMessage.State=s2i(UAVSTATE)
m_selfMessage.Label=m_nLabel m_selfMessage.Label=m_nLabel
m_vecNodes[m_nLabel].State="ASSIGNED" m_vecNodes[m_nLabel].State="ASSIGNED"
#record neighbor distance #record neighbor distance
@ -471,14 +441,14 @@ while(i<m_neighbourCount){
} }
m_navigation.x=0.0 m_navigation.x=0.0
m_navigation.y=0.0 m_navigation.y=0.0
uav_moveto(m_navigation.x,m_navigation.y) uav_moveto(m_navigation.x, m_navigation.y, 0.0)
} }
# #
# Do free # Do free
# #
function DoFree() { function DoFree() {
m_selfMessage.State=s2i(m_eState) m_selfMessage.State=s2i(UAVSTATE)
#wait for a while before looking for a Label #wait for a while before looking for a Label
if(m_unWaitCount>0) if(m_unWaitCount>0)
@ -535,7 +505,7 @@ function DoFree() {
# Limit the mvt # Limit the mvt
if(math.vec2.length(m_navigation)>ROBOT_MAXVEL*2) if(math.vec2.length(m_navigation)>ROBOT_MAXVEL*2)
m_navigation = math.vec2.scale(m_navigation, ROBOT_MAXVEL*2/math.vec2.length(m_navigation)) m_navigation = math.vec2.scale(m_navigation, ROBOT_MAXVEL*2/math.vec2.length(m_navigation))
uav_moveto(m_navigation.x/100.0,m_navigation.y/100.0) uav_moveto(m_navigation.x/100.0, m_navigation.y/100.0, 0.0)
}else{ #no joined robots in sight }else{ #no joined robots in sight
i=0 i=0
var tempvec={.x=0.0,.y=0.0} var tempvec={.x=0.0,.y=0.0}
@ -545,7 +515,7 @@ function DoFree() {
i=i+1 i=i+1
} }
m_navigation=math.vec2.scale(tempvec,1.0/i) m_navigation=math.vec2.scale(tempvec,1.0/i)
uav_moveto(m_navigation.x/100.0,m_navigation.y/100.0) uav_moveto(m_navigation.x/100.0, m_navigation.y/100.0, 0.0)
} }
@ -554,10 +524,10 @@ function DoFree() {
if(step_cunt<=1){ if(step_cunt<=1){
m_navigation.x=0.0 m_navigation.x=0.0
m_navigation.y=0.0 m_navigation.y=0.0
uav_moveto(m_navigation.x/100.0,m_navigation.y/100.0) uav_moveto(m_navigation.x/100.0, m_navigation.y/100.0, 0.0)
} }
#set message #set message
m_selfMessage.State=s2i(m_eState) m_selfMessage.State=s2i(UAVSTATE)
} }
@ -576,8 +546,10 @@ function DoAsking(){
#the request Label be the same as requesed #the request Label be the same as requesed
#get a respond #get a respond
if(m_MessageState[i]=="STATE_JOINED"){ if(m_MessageState[i]=="STATE_JOINED"){
log("received label = ",m_MessageReqLabel[i])
if(m_MessageReqLabel[i]==m_nLabel) if(m_MessageReqLabel[i]==m_nLabel)
if(m_MessageResponse[i]!="REQ_NONE"){ if(m_MessageResponse[i]!="REQ_NONE"){
log("get response")
psResponse=i psResponse=i
}} }}
i=i+1 i=i+1
@ -586,7 +558,7 @@ function DoAsking(){
if(psResponse==-1){ if(psResponse==-1){
#no response, wait #no response, wait
m_unWaitCount=m_unWaitCount-1 m_unWaitCount=m_unWaitCount-1
m_selfMessage.State=s2i(m_eState) m_selfMessage.State=s2i(UAVSTATE)
m_selfMessage.ReqLabel=m_nLabel m_selfMessage.ReqLabel=m_nLabel
m_selfMessage.ReqID=m_unRequestId m_selfMessage.ReqID=m_unRequestId
if(m_unWaitCount==0){ if(m_unWaitCount==0){
@ -595,6 +567,7 @@ function DoAsking(){
} }
} }
else{ else{
log("respond id=",m_MessageReqID[psResponse])
if(m_MessageReqID[psResponse]!=m_unRequestId){ if(m_MessageReqID[psResponse]!=m_unRequestId){
m_vecNodes[m_nLabel].State="ASSIGNING" m_vecNodes[m_nLabel].State="ASSIGNING"
m_vecNodes[m_nLabel].StateAge=m_unJoiningLostPeriod m_vecNodes[m_nLabel].StateAge=m_unJoiningLostPeriod
@ -603,7 +576,6 @@ function DoAsking(){
if(m_MessageReqID[psResponse]==m_unRequestId){ if(m_MessageReqID[psResponse]==m_unRequestId){
if(m_MessageResponse[psResponse]=="REQ_GRANTED"){ if(m_MessageResponse[psResponse]=="REQ_GRANTED"){
TransitionToJoining() TransitionToJoining()
#TransitionToJoined()
return return
} }
else{ else{
@ -614,7 +586,7 @@ function DoAsking(){
} }
m_navigation.x=0.0 m_navigation.x=0.0
m_navigation.y=0.0 m_navigation.y=0.0
uav_moveto(m_navigation.x/100.0,m_navigation.y/100.0) uav_moveto(m_navigation.x/100.0, m_navigation.y/100.0, 0.0)
} }
# #
@ -653,7 +625,7 @@ function DoJoining(){
#the vector from self to target in global coordinate #the vector from self to target in global coordinate
var S2Target=math.vec2.add(S2Pred,P2Target) var S2Target=math.vec2.add(S2Pred,P2Target)
#change the vector to local coordinate of self #change the vector to local coordinate of self
var S2Target_bearing=Angle(S2Target) var S2Target_bearing=math.atan(S2Target.y, S2Target.x)
m_bias=m_cMeToPred.Bearing-S2PGlobalBearing m_bias=m_cMeToPred.Bearing-S2PGlobalBearing
S2Target_bearing=S2Target_bearing+m_bias S2Target_bearing=S2Target_bearing+m_bias
@ -662,7 +634,7 @@ function DoJoining(){
S2Target = math.vec2.scale(S2Target, ROBOT_MAXVEL/math.vec2.length(S2Target)) S2Target = math.vec2.scale(S2Target, ROBOT_MAXVEL/math.vec2.length(S2Target))
m_navigation=math.vec2.newp(math.vec2.length(S2Target),S2Target_bearing) m_navigation=math.vec2.newp(math.vec2.length(S2Target),S2Target_bearing)
uav_moveto(m_navigation.x/100.0,m_navigation.y/100.0) uav_moveto(m_navigation.x/100.0, m_navigation.y/100.0, 0.0)
@ -683,7 +655,7 @@ function DoJoining(){
} }
#pack the communication package #pack the communication package
m_selfMessage.State=s2i(m_eState) m_selfMessage.State=s2i(UAVSTATE)
m_selfMessage.Label=m_nLabel m_selfMessage.Label=m_nLabel
} }
@ -692,7 +664,7 @@ function DoJoining(){
#Do joined #Do joined
# #
function DoJoined(){ function DoJoined(){
m_selfMessage.State=s2i(m_eState) m_selfMessage.State=s2i(UAVSTATE)
m_selfMessage.Label=m_nLabel m_selfMessage.Label=m_nLabel
#collect all requests #collect all requests
@ -705,10 +677,13 @@ function DoJoined(){
while(i<m_neighbourCount){ while(i<m_neighbourCount){
if(m_MessageState[i]=="STATE_ASKING"){ if(m_MessageState[i]=="STATE_ASKING"){
ReqLabel=m_MessageReqLabel[i] ReqLabel=m_MessageReqLabel[i]
log("ReqLabel var:",ReqLabel)
log("M_vec var",m_vecNodes[ReqLabel].State)
if(m_vecNodes[ReqLabel].State=="UNASSIGNED") if(m_vecNodes[ReqLabel].State=="UNASSIGNED")
if(m_nLabel==m_vecNodes[ReqLabel].Pred){ if(m_nLabel==m_vecNodes[ReqLabel].Pred){
#is a request, store the index #is a request, store the index
mapRequests[j]=i mapRequests[j]=i
log("Into if m_nLabel")
j=j+1 j=j+1
} }
} }
@ -745,6 +720,8 @@ function DoJoined(){
m_selfMessage.ReqID=ReqID m_selfMessage.ReqID=ReqID
m_selfMessage.Response=r2i("REQ_GRANTED") m_selfMessage.Response=r2i("REQ_GRANTED")
m_vecNodes[ReqLabel].State="ASSIGNING" m_vecNodes[ReqLabel].State="ASSIGNING"
log("Label=",ReqLabel)
log("ID=",ReqID)
m_vecNodes[ReqLabel].StateAge=m_unJoiningLostPeriod m_vecNodes[ReqLabel].StateAge=m_unJoiningLostPeriod
} }
@ -760,7 +737,7 @@ function DoJoined(){
m_navigation.x=0.0 m_navigation.x=0.0
m_navigation.y=0.0 m_navigation.y=0.0
uav_moveto(m_navigation.x/100.0,m_navigation.y/100.0) uav_moveto(m_navigation.x/100.0, m_navigation.y/100.0, 0.0)
#check if should to transists to lock #check if should to transists to lock
@ -776,25 +753,28 @@ function DoJoined(){
#Do Lock #Do Lock
# #
function DoLock(){ function DoLock(){
m_selfMessage.State=s2i(m_eState) m_selfMessage.State=s2i(UAVSTATE)
m_selfMessage.Label=m_nLabel m_selfMessage.Label=m_nLabel
m_navigation.x=0.0 m_navigation.x=0.0
m_navigation.y=0.0 m_navigation.y=0.0
#calculate motion vection #calculate motion vection
if(m_nLabel==0){ if(m_nLabel==0){
m_navigation.x=0.25 #change value so that robot 0 will move m_navigation.x=0.0 #change value so that robot 0 will move
m_navigation.y=0.0 m_navigation.y=0.0
} }
if(m_nLabel!=0){ if(m_nLabel!=0){
m_navigation=motion_vector() m_navigation=motion_vector()
} }
#move #move
uav_moveto(m_navigation.x,m_navigation.y) uav_moveto(m_navigation.x, m_navigation.y, 0.0)
} }
function action(){ function action(){
statef=action statef=action
UAVSTATE="GRAPH" UAVSTATE="STATE_FREE"
# reset the graph
Reset()
} }
# #
@ -802,11 +782,11 @@ function action(){
# #
function init() { function init() {
# #
#Adjust parameters here # Global parameters for graph formation
# #
m_unResponseTimeThreshold=10 m_unResponseTimeThreshold=10
m_unLabelSearchWaitTime=10 m_unLabelSearchWaitTime=10
m_fTargetDistanceTolerance=50 m_fTargetDistanceTolerance=100
m_fTargetAngleTolerance=0.1 m_fTargetAngleTolerance=0.1
m_unJoiningLostPeriod=100 m_unJoiningLostPeriod=100
@ -814,52 +794,53 @@ function init() {
# Join Swarm # Join Swarm
# #
uav_initswarm() uav_initswarm()
v_tag = stigmergy.create(m_lockstig) v_tag = stigmergy.create(m_lockstig)
uav_initstig() uav_initstig()
Reset() # go to diff. height since no collision avoidance implemented yet
TARGET_ALTITUDE = 2.5 + id * 1.5 TARGET_ALTITUDE = 7.5 #2.5 + id * 1.5
statef=turnedoff
UAVSTATE = "TURNEDOFF"
} }
# #
# Executed every step # Executed every step
# #
function step(){ function step() {
# listen to potential RC
uav_rccmd() uav_rccmd()
# get the swarm commands
uav_neicmd() uav_neicmd()
uav_updatestig() # update the vstig (status/net/batt)
uav_updatestig()
#update the graph #update the graph
UpdateNodeInfo() UpdateNodeInfo()
#reset message package to be sent #reset message package to be sent
m_selfMessage={.State=s2i("STATE_FREE"),.Label=0,.ReqLabel=0,.ReqID=0,.Response=r2i("REQ_NONE")} m_selfMessage={.State=s2i("STATE_FREE"),.Label=0,.ReqLabel=0,.ReqID=0,.Response=r2i("REQ_NONE")}
# #
#act according to current state # graph state machine
# #
if(UAVSTATE=="GRAPH"){ if(UAVSTATE=="STATE_FREE")
if(m_eState=="STATE_FREE") statef=DoFree
DoFree() else if(UAVSTATE=="STATE_ESCAPE")
else if(m_eState=="STATE_ESCAPE") statef=DoEscape
DoEscape() else if(UAVSTATE=="STATE_ASKING")
else if(m_eState=="STATE_ASKING") statef=DoAsking
DoAsking() else if(UAVSTATE=="STATE_JOINING")
else if(m_eState=="STATE_JOINING") statef=DoJoining
DoJoining() else if(UAVSTATE=="STATE_JOINED")
else if(m_eState=="STATE_JOINED") statef=DoJoined
DoJoined() else if(UAVSTATE=="STATE_LOCK")
else if(m_eState=="STATE_LOCK") statef=DoLock
DoLock()
}
# high level UAV state machine
statef() statef()
log("Current state: ", UAVSTATE, " and label: ", m_nLabel)
debug(m_eState,m_nLabel)
log("Current state: ", UAVSTATE)
log("Swarm size: ", ROBOTS) log("Swarm size: ", ROBOTS)
# if(id==0)
# stattab_print()
#navigation #navigation
#broadcast messag #broadcast message
neighbors.broadcast("m",packmessage(m_selfMessage)) neighbors.broadcast("m",packmessage(m_selfMessage))
# #
@ -882,12 +863,8 @@ function step(){
# Executed when reset # Executed when reset
# #
function Reset(){ function Reset(){
# m_vecNodes={}
# m_vecNodes = parse_graph("/home/dave/ROS_WS/src/rosbuzz/buzz_scripts/include/Graph_drone.graph")#change the .graph file when necessary
# m_vecNodes_fixed={}
# m_vecNodes_fixed=parse_graph_fixed("/home/dave/ROS_WS/src/rosbuzz/buzz_scripts/include/Graph_fixed.graph")
Read_Graph() Read_Graph()
m_nLabel=-1 m_nLabel=-1
#start listening #start listening
start_listen() start_listen()
@ -895,7 +872,7 @@ function Reset(){
#set initial state, only one robot choose [A], while the rest choose [B] #set initial state, only one robot choose [A], while the rest choose [B]
# #
#[A]The robot used to triger the formation process is defined as joined, #[A]The robot used to triger the formation process is defined as joined,
if(id==0){ if(id==ROOT_ID){
m_nLabel=0 m_nLabel=0
TransitionToJoined() TransitionToJoined()
} }
@ -912,7 +889,7 @@ function destroy() {
#clear neighbour message #clear neighbour message
m_navigation.x=0.0 m_navigation.x=0.0
m_navigation.y=0.0 m_navigation.y=0.0
uav_moveto(m_navigation.x/100.0,m_navigation.y/100.0) uav_moveto(m_navigation.x/100.0, m_navigation.y/100.0, 0.0)
m_vecNodes={} m_vecNodes={}
#stop listening #stop listening
neighbors.ignore("m") neighbors.ignore("m")

View File

@ -1,826 +0,0 @@
#
# Include files
#
include "string.bzz"
include "vec2.bzz"
include "update.bzz"
include "barrier.bzz" # don't use a stigmergy id=11 with this header.
include "uavstates.bzz" # require an 'action' function to be defined here.
ROBOT_RADIUS=50
ROBOT_DIAMETER=2.0*ROBOT_RADIUS
ROBOT_SAFETYDIST=2.0*ROBOT_DIAMETER
#
# Global variables
#
#
#Save message from all neighours
#the indexes are as 1,2,3..., while each value is a table that store the information of a neighbour robot
m_MessageState={}#store received neighbour message
m_MessageLable={}#store received neighbour message
m_MessageReqLable={}#store received neighbour message
m_MessageReqID={}#store received neighbour message
m_MessageSide={}#store received neighbour message
m_MessageResponse={}#store received neighbour message
m_MessageRange={}#store received neighbour message
m_MessageBearing={}#store received neighbour message
m_neighbourCunt=0#used to cunt neighbours
#Save message from one neighbour
#the indexes are as State(received state),Lable(received lable),ReqLable,ReqID,Side,Response,Range,Bearing
m_receivedMessage={.State="STATE_FREE",.Lable=0,.ReqLable=0,.ReqID=0,.Side=0,.Response="REQ_NONE",.Range=0,.Bearing=0}
#
#Save the message to send
#The keys of the talbe is State(current state),Lable(current lable),ReqLable(requested lable),ReqID(request id),Side(side),Response(reply message{REQ_NONE,REQ_GRANTED,REQ_RESEND})
m_selfMessage={.State="STATE_FREE",.Lable=0,.ReqLable=0,.ReqID=0,.Side=0,.Response="REQ_NONE"}
#Current robot state
m_eState="STATE_FREE"
#navigation vector
m_navigation={.x=0,.y=0}
#Debug message to be displayed in qt-opengl
#m_ossDebugMsg
#Debug vector to draw
#CVector2 m_cDebugVector
#Table of the nodes in the graph
m_vecNodes={}
m_vecNodes_fixed={}
#Current label being requested or chosen (-1 when none)
m_nLabel=-1
#Label request id
m_unRequestId=0
#Side
m_unbSide=0
#Global bias, used to map local coordinate to global coordinate
m_bias=0
#Vector to predecessor,range is the distance between robots, bearing is the angle of pred wrt self in local coordinate of self, globalbearing is the angle of self wrt pred in global coordinate
m_cMeToPred={.Range=0.0,.Bearing=0.0,.GlobalBearing=0.0}
#Counter to wait for something to happen
m_unWaitCount=0
#Number of steps to wait before looking for a free label
m_unLabelSearchWaitTime=0
#Number of steps to wait for an answer to be received
m_unResponseTimeThreshold=0
#Number of steps to wait until giving up joining
m_unJoiningLostPeriod=0
#Tolerance distance to a target location
m_fTargetDistanceTolerance=0
#step cunt
step_cunt=0
#virtual stigmergy
v_tag = stigmergy.create(1)
# Lennard-Jones parameters
EPSILON = 13.5 #3.5
# Lennard-Jones interaction magnitude
function FlockInteraction(dist,target,epsilon){
var mag = -(epsilon / dist) * ((target / dist)^4 - (target / dist)^2)
return mag
}
function LimitAngle(angle){
if(angle>2*math.pi)
return angle-2*math.pi
else if (angle<0)
return angle+2*math.pi
else
return angle
}
#
# Calculates the angle of the given vector2.
# PARAM v: The vector2.
# RETURN: The angle of the vector.
#
Angle = function(v) {
return math.atan(v.y, v.x)
}
#
#return the number of value in table
#
function count(table,value){
var number=0
var i=0
while(i<size(table)){
if(table[i]==value){
number=number+1
}
i=i+1
}
return number
}
#
#return the index of value
#
function find(table,value){
var index=nil
var i=0
while(i<size(table)){
if(table[i]==value)
index=i
i=i+1
}
return index
}
function pow(base,exponent){
var i=0
var renturn_val=1
if(exponent==0)
return 1
else{
while(i<exponent){
renturn_val=renturn_val*base
i=i+1
}
return renturn_val
}
}
#
# Graph parsing
#
function parse_graph(fname) {
# Graph data
var gd = {}
# Open the file
var fd = io.fopen(fname, "r")
if(not fd) {
log("Can't open '", fname, "'")
return nil
}
# Parse the file line by line
var rrec # Record read from line
var grec # Record parsed into graph
io.fforeach(fd, function(line) {
# Parse file line
rrec = string.split(line, "\t ")
# Make record
gd[string.toint(rrec[0])] = { # The .graph file is stored according the sequence of lable, predecessor, distance, bearing
.Lable = string.toint(rrec[0]), # Lable of the point
.Pred = string.toint(rrec[1]), # Lable of its predecessor
.distance = string.tofloat(rrec[2]), # distance to the predecessor
.bearing = string.tofloat(rrec[3]), # bearing form the predecessor to this dot
.State="UNASSIGNED",
.StateAge=0
}})
# All done
io.fclose(fd)
return gd
}
function parse_graph_fixed(fname) {
# Graph data
var gd = {}
# Open the file
var fd = io.fopen(fname, "r")
if(not fd) {
log("Can't open '", fname, "'")
return nil
}
# Parse the file line by line
var rrec # Record read from line
var grec # Record parsed into graph
io.fforeach(fd, function(line) {
# Parse file line
rrec = string.split(line, "\t ")
# Make record
gd[string.toint(rrec[0])] = { # The .graph file is stored according the sequence of lable, pre1, dis2pr1, pre2, ids2pre2, side
.Pred1 = string.toint(rrec[1]), # Pred 1 lable
.Pred2 = string.toint(rrec[3]), # Pred 2 lable
.d1 = string.tofloat(rrec[2]), # Pred 1 distance
.d2 = string.tofloat(rrec[4]), # Pred 2 distance
#.S = string.toint(rrec[5]), # Side
.Lable=string.toint(rrec[0]),
.State="UNASSIGNED",
.StateAge=0
}})
# All done
io.fclose(fd)
return gd
}
function start_listen(){
neighbors.listen("msg",
function(vid,value,rid){
#store the received message
var temp_id=rid
m_receivedMessage.State=value.State
m_receivedMessage.Lable=value.Lable
m_receivedMessage.ReqLable=value.ReqLable
m_receivedMessage.ReqID=value.ReqID
m_receivedMessage.Side=value.Side
m_receivedMessage.Response=value.Response
Get_DisAndAzi(temp_id)
#add the received message
#
m_MessageState[m_neighbourCunt]=value.State
m_MessageLable[m_neighbourCunt]=value.Lable
m_MessageReqLable[m_neighbourCunt]=value.ReqLable
m_MessageReqID[m_neighbourCunt]=value.ReqID
m_MessageSide[m_neighbourCunt]=value.Side
m_MessageResponse[m_neighbourCunt]=value.Response
m_MessageRange[m_neighbourCunt]=m_receivedMessage.Range
m_MessageBearing[m_neighbourCunt]=m_receivedMessage.Bearing
m_neighbourCunt=m_neighbourCunt+1
})
}
#
#Function used to get the station info of the sender of the message
function Get_DisAndAzi(id){
neighbors.foreach(
function(rid, data) {
if(rid==id){
m_receivedMessage.Range=data.distance*100.0
m_receivedMessage.Bearing=data.azimuth
}
})
}
#
#Update node info according to neighbour robots
#
function UpdateNodeInfo(){
#Collect informaiton
#Update information
var i=0
while(i<m_neighbourCunt){
if(m_MessageState[i]=="STATE_JOINED"){
m_vecNodes[m_MessageLable[i]].State="ASSIGNED"
m_vecNodes[m_MessageLable[i]].StateAge=m_unJoiningLostPeriod
}
else if(m_MessageState[i]=="STATE_JOINING"){
m_vecNodes[m_MessageLable[i]].State="ASSIGNING"
m_vecNodes[m_MessageLable[i]].StateAge=m_unJoiningLostPeriod
}
i=i+1
}
#Forget old information
i=0
while(i<size(m_vecNodes)){
if((m_vecNodes[i].StateAge>0) and (m_vecNodes[i].State=="ASSIGNING")){
m_vecNodes[i].StateAge=m_vecNodes[i].StateAge-1
if(m_vecNodes[i].StateAge==0)
m_vecNodes[i].State="UNASSIGNED"
}
i=i+1
}
}
#
#Transistion to state free
#
function TransitionToFree(){
m_eState="STATE_FREE"
m_unWaitCount=m_unLabelSearchWaitTime
m_selfMessage.State=m_eState
}
#
#Transistion to state asking
#
function TransitionToAsking(un_label){
m_eState="STATE_ASKING"
m_nLabel=un_label
m_unRequestId=rng.uniform(0,65536)+id#don't know why the random numbers are the same, add id to make the ReqID different
m_selfMessage.State=m_eState
m_selfMessage.ReqLable=m_nLabel
m_selfMessage.ReqID=m_unRequestId
m_unWaitCount=m_unResponseTimeThreshold
}
#
#Transistion to state joining
#
function TransitionToJoining(){
m_eState="STATE_JOINING"
m_selfMessage.State=m_eState
m_selfMessage.Lable=m_nLabel
m_unWaitCount=m_unJoiningLostPeriod
neighbors.listen("reply",
function(vid,value,rid){
#store the received message
if(value.Lable==m_nLabel){
m_cMeToPred.GlobalBearing=value.GlobalBearing
}
})
}
#
#Transistion to state joined
#
function TransitionToJoined(){
m_eState="STATE_JOINED"
m_selfMessage.State=m_eState
m_selfMessage.Lable=m_nLabel
m_vecNodes[m_nLabel].State="ASSIGNED"
neighbors.ignore("reply")
#write statues
v_tag.put(m_nLabel, 1)
m_navigation.x=0.0
m_navigation.y=0.0
uav_moveto(m_navigation.x/100.0,m_navigation.y/100.0)
}
#
#Transistion to state Lock, lock the current formation
#
function TransitionToLock(){
m_eState="STATE_LOCK"
m_selfMessage.State=m_eState
m_selfMessage.Lable=m_nLabel
m_vecNodes[m_nLabel].State="ASSIGNED"
m_navigation.x=0.0
m_navigation.y=0.0
uav_moveto(m_navigation.x/100.0,m_navigation.y/100.0)
}
#
# Do free
#
function DoFree() {
m_selfMessage.State=m_eState
#wait for a while before looking for a lable
if(m_unWaitCount>0)
m_unWaitCount=m_unWaitCount-1
#find a set of joined robots
var setJoinedLables={}
var setJoinedIndexes={}
var i=0
var j=0
while(i<m_neighbourCunt){
if(m_MessageState[i]=="STATE_JOINED"){
setJoinedLables[j]=m_MessageLable[i]
setJoinedIndexes[j]=i
j=j+1
}
i=i+1
}
#go through the graph to look for a proper lable
var unFoundLable=0
var IDofPred=0
i=1
while(i<size(m_vecNodes) and (unFoundLable==0)){
#if the node is unassigned and the predecessor is insight
if(m_vecNodes[i].State=="UNASSIGNED" and count(setJoinedLables,m_vecNodes[i].Pred)==1){
unFoundLable=m_vecNodes[i].Lable
IDofPred=find(m_MessageLable,m_vecNodes[unFoundLable].Pred)
}
i=i+1
}
if(unFoundLable>0){
TransitionToAsking(unFoundLable)
return
}
#navigation
#if there is a joined robot within sight, move around joined robots
#else, gather with other free robots
if(size(setJoinedIndexes)>0){
var tempvec_P={.x=0.0,.y=0.0}
var tempvec_N={.x=0.0,.y=0.0}
i=0
while(i<size(setJoinedIndexes)){
var index=setJoinedIndexes[i]
tempvec_P=math.vec2.add(tempvec_P,math.vec2.newp(m_MessageRange[index],m_MessageBearing[index]+0.5*math.pi))
tempvec_N=math.vec2.add(tempvec_N,math.vec2.newp(m_MessageRange[index]-5.0*ROBOT_SAFETYDIST,m_MessageBearing[index]))
i=i+1
}
tempvec_P=math.vec2.scale(tempvec_P,size(setJoinedIndexes))
tempvec_N=math.vec2.scale(tempvec_N,size(setJoinedIndexes))
m_navigation=math.vec2.add(tempvec_P,tempvec_N)
uav_moveto(m_navigation.x/100.0,m_navigation.y/100.0)
}else{ #no joined robots in sight
i=0
var tempvec={.x=0.0,.y=0.0}
while(i<m_neighbourCunt){
tempvec=math.vec2.add(tempvec,math.vec2.newp(m_MessageRange[i]-2.0*ROBOT_SAFETYDIST,m_MessageBearing[i]))
i=i+1
}
m_navigation=math.vec2.scale(tempvec,1.0/i)
uav_moveto(m_navigation.x/100.0,m_navigation.y/100.0)
}
#jump the first step
if(step_cunt<=1){
uav_moveto(0.0,0.0)
}
#set message
m_selfMessage.State=m_eState
}
#
#Do asking
#
function DoAsking(){
#look for response from predecessor
var i=0
var psResponse=-1
while(i<m_neighbourCunt and psResponse==-1){
#the respond robot in joined state
#the request lable be the same as requesed
#get a respond
if(m_MessageState[i]=="STATE_JOINED"){
if(m_MessageReqLable[i]==m_nLabel)
if(m_MessageResponse[i]!="REQ_NONE"){
psResponse=i
}}
i=i+1
}
#analyse response
if(psResponse==-1){
#no response, wait
m_unWaitCount=m_unWaitCount-1
m_selfMessage.State=m_eState
m_selfMessage.ReqLable=m_nLabel
m_selfMessage.ReqID=m_unRequestId
if(m_unWaitCount==0){
TransitionToFree()
return
}
}
else{
if(m_MessageReqID[psResponse]!=m_unRequestId)
TransitionToFree()
if(m_MessageReqID[psResponse]==m_unRequestId){
if(m_MessageResponse[psResponse]=="REQ_GRANTED"){
TransitionToJoining()
#TransitionToJoined()
return
}
else{
TransitionToAsking(m_nLabel)
return
}
}
}
uav_moveto(0.0,0.0)
}
#
#Do joining
#
function DoJoining(){
#get information of pred
var i=0
var IDofPred=-1
while(i<m_neighbourCunt and IDofPred==-1){
if(m_MessageLable[i]==m_vecNodes[m_nLabel].Pred and m_MessageState[i]=="STATE_JOINED")
IDofPred=i
i=i+1
}
#found pred
if(IDofPred!=-1){
m_unWaitCount=m_unJoiningLostPeriod#if see pred, reset the timer
var P2Target=math.vec2.newp(m_vecNodes[m_nLabel].distance,m_vecNodes[m_nLabel].bearing)
m_cMeToPred.Range=m_MessageRange[IDofPred]#the poition of self to pred in local coordinate
m_cMeToPred.Bearing=m_MessageBearing[IDofPred]
#attention, m_cMeToPred.GlobalBearing is the bearing of self wrt pred in global coordinate
var S2PGlobalBearing=0
#m_cMeToPred.GlobalBearing=LimitAngle(m_cMeToPred.GlobalBearing)
if(m_cMeToPred.GlobalBearing>math.pi)
S2PGlobalBearing=m_cMeToPred.GlobalBearing-math.pi
else
S2PGlobalBearing=m_cMeToPred.GlobalBearing+math.pi
var S2Pred=math.vec2.newp(m_cMeToPred.Range,S2PGlobalBearing)
#the vector from self to target in global coordinate
var S2Target=math.vec2.add(S2Pred,P2Target)
#change the vector to local coordinate of self
var S2Target_bearing=Angle(S2Target)
m_bias=m_cMeToPred.Bearing-S2PGlobalBearing
#S2Target_bearing=S2Target_bearing+m_bias # commented out by DS'06/17
m_navigation=math.vec2.newp(math.vec2.length(S2Target),S2Target_bearing)
uav_moveto(m_navigation.x/100.0,m_navigation.y/100.0)
#test if is already in desired position
if(math.abs(S2Target.x)<m_fTargetDistanceTolerance and math.abs(S2Target.y)<m_fTargetDistanceTolerance){
#log(S2Target_dis,S2Target_bearing)
TransitionToJoined()
return
}
} else{ #miss pred, there is a change the another robot block the sight, keep moving as before for sometime
m_unWaitCount=m_unWaitCount-1
}
if(m_unWaitCount==0){
TransitionToFree()
return
}
#pack the communication package
m_selfMessage.State=m_eState
m_selfMessage.Lable=m_nLabel
}
#
#Do joined
#
function DoJoined(){
m_selfMessage.State=m_eState
m_selfMessage.Lable=m_nLabel
#collect all requests
var mapRequests={}
var i=0
var j=0
var ReqLable
var JoiningLable
var seenPred=0
while(i<m_neighbourCunt){
if(m_MessageState[i]=="STATE_ASKING"){
ReqLable=m_MessageReqLable[i]
if(m_vecNodes[ReqLable].State=="UNASSIGNED")
if(m_nLabel==m_vecNodes[ReqLable].Pred){
#is a request, store the index
mapRequests[j]=i
j=j+1
}
}
if(m_MessageState[i]=="STATE_JOINING"){
JoiningLable=m_MessageLable[i]
if(m_nLabel==m_vecNodes[JoiningLable].Pred){
##joining wrt this dot,send the global bearing
var m_messageForJoining={.Lable=JoiningLable,.GlobalBearing=m_MessageBearing[i]-m_bias}
neighbors.broadcast("reply",m_messageForJoining)
}
}
#if it is the pred
if(m_MessageState[i]=="STATE_JOINED" and m_MessageLable[i]==m_vecNodes[m_nLabel].Pred){
seenPred=1
m_unWaitCount=m_unJoiningLostPeriod
}
i=i+1
}
#get request
if(size(mapRequests)!=0){
i=1
var ReqIndex=0
while(i<size(mapRequests)){
#compare the distance
if(m_MessageRange[mapRequests[ReqIndex]]>m_MessageRange[mapRequests[i]])
ReqIndex=i
i=i+1
}
#get the best index, whose Reqlable and Reqid are
ReqLable=m_MessageReqLable[mapRequests[ReqIndex]]
var ReqID=m_MessageReqID[mapRequests[ReqIndex]]
m_selfMessage.ReqLable=ReqLable
m_selfMessage.ReqID=ReqID
m_selfMessage.Response="REQ_GRANTED"
}
#lost pred, wait for some time and transit to free
#if(seenPred==0){
#m_unWaitCount=m_unWaitCount-1
#if(m_unWaitCount==0){
#TransitionToFree()
#return
#}
#}
m_navigation.x=0.0
m_navigation.y=0.0
uav_moveto(m_navigation.x/100.0,m_navigation.y/100.0)
#check if should to transists to lock
if(v_tag.size()==ROBOTS){
TransitionToLock()
}
}
#
#Do Lock
#
function DoLock(){
m_selfMessage.State=m_eState
m_selfMessage.Lable=m_nLabel
m_navigation.x=0.0
m_navigation.y=0.0
#collect preds information
var i=0
var mypred1={.range=0,.bearing=0}
var mypred2={.range=0,.bearing=0}
while(i<m_neighbourCunt){
#is the first predecessor
if(m_MessageLable[i]==m_vecNodes_fixed[m_nLabel].Pred1){
mypred1.range=m_MessageRange[i]
mypred1.bearing=m_MessageBearing[i]
}
#is the second predecessor
if(m_MessageLable[i]==m_vecNodes_fixed[m_nLabel].Pred2){
mypred2.range=m_MessageRange[i]
mypred2.bearing=m_MessageBearing[i]
}
i=i+1
}
#calculate motion vection
if(m_nLabel==0){
m_navigation.x=0.0
m_navigation.y=0.0
log(";",m_nLabel,";",0)
}
if(m_nLabel==1){
var tempvec={.Range=0.0,.Bearing=0.0}
tempvec.Range=FlockInteraction(mypred1.range,m_vecNodes_fixed[m_nLabel].d1,10)
#tempvec.Range=mypred1.range-m_vecNodes_fixed[m_nLabel].d1
tempvec.Bearing=mypred1.bearing
m_navigation=math.vec2.newp(tempvec.Range,tempvec.Bearing)
log(";",m_nLabel,";",mypred1.range-m_vecNodes_fixed[m_nLabel].d1)
}
if(m_nLabel>1){
var cDir={.x=0.0,.y=0.0}
var cDir1={.x=0.0,.y=0.0}
var cDir2={.x=0.0,.y=0.0}
cDir1=math.vec2.newp(FlockInteraction(mypred1.range,m_vecNodes_fixed[m_nLabel].d1,EPSILON),mypred1.bearing)
cDir2=math.vec2.newp(FlockInteraction(mypred2.range,m_vecNodes_fixed[m_nLabel].d2,EPSILON),mypred2.bearing)
#cDir1=math.vec2.newp((mypred1.range-m_vecNodes_fixed[m_nLabel].d1),mypred1.bearing)
#cDir2=math.vec2.newp((mypred2.range-m_vecNodes_fixed[m_nLabel].d2),mypred2.bearing)
cDir=math.vec2.add(cDir1,cDir2)
cDir=math.vec2.scale(cDir,100)
m_navigation.x=cDir.x
m_navigation.y=cDir.y
#log(m_nLabel,"error:",mypred1.range-m_vecNodes_fixed[m_nLabel].d1,"and",mypred2.range-m_vecNodes_fixed[m_nLabel].d2)
log(";",m_nLabel,";",mypred1.range-m_vecNodes_fixed[m_nLabel].d1)
}
#move
uav_moveto(m_navigation.x,m_navigation.y)
}
function action(){
statef=action
UAVSTATE="GRAPH"
}
#
# Executed at init
#
function init() {
#
#Adjust parameters here
#
m_unResponseTimeThreshold=10
m_unLabelSearchWaitTime=10
m_fTargetDistanceTolerance=10
m_unJoiningLostPeriod=100
#
# Join Swarm
#
uav_initswarm()
Reset();
}
#
# Executed every step
#
function step(){
uav_rccmd()
uav_neicmd()
#update the graph
UpdateNodeInfo()
#reset message package to be sent
m_selfMessage={.State="STATE_FREE",.Lable=0,.ReqLable=0,.ReqID=0,.Side=0,.Response="REQ_NONE"}
#
#act according to current state
#
if(UAVSTATE=="GRAPH"){
if(m_eState=="STATE_FREE")
DoFree()
else if(m_eState=="STATE_ESCAPE")
DoEscape()
else if(m_eState=="STATE_ASKING")
DoAsking()
else if(m_eState=="STATE_JOINING")
DoJoining()
else if(m_eState=="STATE_JOINED")
DoJoined()
else if(m_eState=="STATE_LOCK")
DoLock()
}
statef()
debug(m_eState,m_nLabel)
log("Current state: ", UAVSTATE)
log("Swarm size: ", ROBOTS)
#navigation
#broadcast messag
neighbors.broadcast("msg",m_selfMessage)
#
#clean message storage
m_MessageState={}#store received neighbour message
m_MessageLable={}#store received neighbour message
m_MessageReqLable={}#store received neighbour message
m_MessageReqID={}#store received neighbour message
m_MessageSide={}#store received neighbour message
m_MessageResponse={}#store received neighbour message
m_MessageRange={}#store received neighbour message
m_MessageBearing={}#store received neighbour message
m_neighbourCunt=0
#step cunt+1
step_cunt=step_cunt+1
}
#
# Executed when reset
#
function Reset(){
m_vecNodes={}
m_vecNodes = parse_graph("/home/dave/ROS_WS/src/rosbuzz/buzz_scripts/include/Graph_drone.graph")#change the .graph file when necessary
m_vecNodes_fixed={}
m_vecNodes_fixed=parse_graph_fixed("/home/dave/ROS_WS/src/rosbuzz/buzz_scripts/include/Graph_fixed.graph")
m_nLabel=-1
#start listening
start_listen()
#
#set initial state, only one robot choose [A], while the rest choose [B]
#
#[A]The robot used to triger the formation process is defined as joined,
if(id==0){
m_nLabel=0
TransitionToJoined()
}
#[B]Other robots are defined as free.
else{
TransitionToFree()
}
}
#
# Executed upon destroy
#
function destroy() {
#clear neighbour message
uav_moveto(0.0,0.0)
m_vecNodes={}
#stop listening
neighbors.ignore("msg")
}

View File

@ -0,0 +1,849 @@
#
# Include files
#
include "string.bzz"
include "vec2.bzz"
include "update.bzz"
#include "vstigenv.bzz" # reserve stigmergy id=20 and 21 for this header.
include "barrier.bzz" # reserve stigmergy id=80 (auto-increment up) for this header.
include "uavstates.bzz" # require an 'action' function to be defined here.
include "graphs/shapes_P.bzz"
include "graphs/shapes_O.bzz"
include "graphs/shapes_L.bzz"
include "graphs/shapes_Y.bzz"
ROBOT_RADIUS = 50
ROBOT_DIAMETER = 2.0*ROBOT_RADIUS
ROBOT_SAFETYDIST = 2.0*ROBOT_DIAMETER
ROOT_ID = 2
old_state = -1
# max velocity in cm/step
ROBOT_MAXVEL = 150.0
#
# Global variables
#
#
# Save message from all neighours
#the indexes are as 1,2,3..., while each value is a table that store the information of a neighbour robot
m_MessageState={}#store received neighbour message
m_MessageLabel={}#store received neighbour message
m_MessageReqLabel={}#store received neighbour message
m_MessageReqID={}#store received neighbour message
m_MessageResponse={}#store received neighbour message
m_MessageRange={}#store received neighbour message
m_MessageBearing={}#store received neighbour message
m_neighbourCount=0#used to cunt neighbours
#Save message from one neighbour
#the indexes are as State(received state),Label(received Label),ReqLabel,ReqID,Response,Range,Bearing
m_receivedMessage={.State=s2i("STATE_FREE"),.Label=0,.ReqLabel=0,.ReqID=0,.Response=r2i("REQ_NONE"),.Range=0,.Bearing=0}
#
#Save the message to send
#The keys of the talbe is State(current state),Label(current Label),ReqLabel(requested Label),ReqID(request id),Response(reply message{REQ_NONE,REQ_GRANTED,REQ_RESEND})
m_selfMessage={.State=s2i("STATE_FREE"),.Label=0,.ReqLabel=0,.ReqID=0,.Response=r2i("REQ_NONE")}
#navigation vector
m_navigation={.x=0,.y=0}
#Current label being requested or chosen (-1 when none)
m_nLabel=-1
m_messageID={}
repeat_assign=0
assign_label=-1
assign_id=-1
m_gotjoinedparent = 0
#neighbor distance to lock the current pattern
lock_neighbor_id={}
lock_neighbor_dis={}
#Label request id
m_unRequestId=0
#Global bias, used to map local coordinate to global coordinate
m_bias=0
#Vector to predecessor,range is the distance between robots, bearing is the angle of pred wrt self in local coordinate of self, globalbearing is the angle of self wrt pred in global coordinate
m_cMeToPred={.Range=0.0,.Bearing=0.0,.GlobalBearing=0.0}
#Counter to wait for something to happen
m_unWaitCount=0
#Number of steps to wait before looking for a free label
m_unLabelSearchWaitTime=0
#Number of steps to wait for an answer to be received
m_unResponseTimeThreshold=0
#Number of steps to wait until giving up joining
m_unJoiningLostPeriod=0
#Tolerance distance to a target location
m_fTargetDistanceTolerance=0
# virtual stigmergy for the LOCK barrier.
m_lockstig = 1
# Lennard-Jones parameters, may need change
EPSILON = 4000 #13.5 the LJ parameter for other robots
# Lennard-Jones interaction magnitude
function FlockInteraction(dist,target,epsilon){
var mag = -(epsilon / dist) * ((target / dist)^4 - (target / dist)^2)
return mag
}
#
#return the number of value in table
#
function count(table,value){
var number=0
var i=0
while(i<size(table)){
if(table[i]==value){
number=number+1
}
i=i+1
}
return number
}
#
#map from int to state
#
function i2s(value){
if(value==1){
return "STATE_FREE"
}
else if(value==2){
return "STATE_ASKING"
}
else if(value==3){
return "STATE_JOINING"
}
else if(value==4){
return "STATE_JOINED"
}
else if(value==5){
return "STATE_LOCK"
}
}
#
#map from state to int
#
function s2i(value){
if(value=="STATE_FREE"){
return 1
}
else if(value=="STATE_ASKING"){
return 2
}
else if(value=="STATE_JOINING"){
return 3
}
else if(value=="STATE_JOINED"){
return 4
}
else if(value=="STATE_LOCK"){
return 5
}
}
#
#map form int to response
#
function i2r(value){
if(value==1){
return "REQ_NONE"
}
else if(value==2){
return "REQ_GRANTED"
}
}
#
#map from response to int
#
function r2i(value){
if(value=="REQ_NONE"){
return 1
}
else if(value=="REQ_GRANTED"){
return 2
}
}
#
#return the index of value
#
function find(table,value){
var ind=nil
var i=0
while(i<size(table)){
if(table[i]==value)
ind=i
i=i+1
}
return ind
}
#
#pack message into 1 number
#
function packmessage(send_table){
var send_value
send_value=100000*send_table.State+10000*send_table.Label+1000*send_table.ReqLabel+10*send_table.ReqID+send_table.Response
return send_value
}
#
#pack guide message into 1 number
#
function pack_guide_msg(send_table){
var send_value
var r_id=send_table.Label#id of target robot
var pon#positive or negative ,0 postive, 1 negative
if(send_table.Bearing>=0){
pon=0
}
else{
pon=1
}
var b=math.abs(send_table.Bearing)
send_value=r_id*1000+pon*100+b
return send_value
}
#
#unpack message
#
function unpackmessage(recv_value){
var wan=(recv_value-recv_value%100000)/100000
recv_value=recv_value-wan*100000
var qian=(recv_value-recv_value%10000)/10000
recv_value=recv_value-qian*10000
var bai=(recv_value-recv_value%1000)/1000
recv_value=recv_value-bai*1000
var shi=(recv_value-recv_value%10)/10
recv_value=recv_value-shi*10
var ge=recv_value
var return_table={.State=0.0,.Label=0.0,.ReqLabel=0.0,.ReqID=0.0,.Response=0.0}
return_table.State=wan
return_table.Label=qian
return_table.ReqLabel=bai
return_table.ReqID=shi
return_table.Response=ge
return return_table
}
#
#unpack guide message
#
function unpack_guide_msg(recv_value){
#log(id,"I pass value=",recv_value)
var qian=(recv_value-recv_value%1000)/1000
recv_value=recv_value-qian*1000
var bai=(recv_value-recv_value%100)/100
recv_value=recv_value-bai*100
var b=recv_value
var return_table={.Label=0.0,.Bearing=0.0}
return_table.Label=qian
if(bai==1){
b=b*-1.0
}
return_table.Bearing=b
return return_table
}
#
#get the target distance to neighbr nei_id
#
function target4label(nei_id){
var return_val="miss"
var i=0
while(i<size(lock_neighbor_id)){
if(lock_neighbor_id[i]==nei_id){
return_val=lock_neighbor_dis[i]
}
i=i+1
}
return return_val
}
#
#calculate LJ vector for neibhor stored in i
#
function LJ_vec(i){
var dis=m_MessageRange[i]
var ljbearing=m_MessageBearing[i]
var nei_id=m_messageID[i]
var target=target4label(nei_id)
var cDir={.x=0.0,.y=0.0}
if(target!="miss"){
cDir=math.vec2.newp(FlockInteraction(dis,target,EPSILON),ljbearing)
}
#log(id,"dis=",dis,"target=",target,"label=",nei_id)
#log("x=",cDir.x,"y=",cDir.y)
return cDir
}
#
#calculate the motion vector
#
function motion_vector(){
var i=0
var m_vector={.x=0.0,.y=0.0}
while(i<m_neighbourCount){
#calculate and add the motion vector
m_vector=math.vec2.add(m_vector,LJ_vec(i))
#log(id,"x=",m_vector.x,"y=",m_vector.y)
i=i+1
}
m_vector=math.vec2.scale(m_vector,1.0/m_neighbourCount)
#log(id,"fnal=","x=",m_vector.x,"y=",m_vector.y)
return m_vector
}
#
# starts the neighbors listener
#
function start_listen(){
neighbors.listen("m",
function(vid,value,rid){
#store the received message
var temp_id=rid
var recv_val=unpackmessage(value)
Get_DisAndAzi(temp_id)
#add the received message
#
m_MessageState[m_neighbourCount]=i2s(recv_val.State)
m_MessageLabel[m_neighbourCount]=recv_val.Label
m_MessageReqLabel[m_neighbourCount]=recv_val.ReqLabel
m_MessageReqID[m_neighbourCount]=recv_val.ReqID
m_MessageResponse[m_neighbourCount]=i2r(recv_val.Response)
m_MessageRange[m_neighbourCount]=m_receivedMessage.Range
m_MessageBearing[m_neighbourCount]=m_receivedMessage.Bearing
m_messageID[m_neighbourCount]=rid
#log(rid, " is in ", m_MessageState[m_neighbourCount], " ", m_MessageLabel[m_neighbourCount])
m_neighbourCount=m_neighbourCount+1
})
}
#
#Function used to get the station info of the sender of the message
#
function Get_DisAndAzi(id){
neighbors.foreach(
function(rid, data) {
if(rid==id){
m_receivedMessage.Range=data.distance*100.0
m_receivedMessage.Bearing=data.azimuth
}
})
}
#
#Update node info according to neighbour robots
#
function UpdateNodeInfo(){
#Collect informaiton
#Update information
var i=0
while(i<m_neighbourCount){
if(m_MessageState[i]=="STATE_JOINED"){
m_vecNodes[m_MessageLabel[i]].State="ASSIGNED"
m_vecNodes[m_MessageLabel[i]].StateAge=m_unJoiningLostPeriod
}
else if(m_MessageState[i]=="STATE_JOINING"){
m_vecNodes[m_MessageLabel[i]].State="ASSIGNING"
m_vecNodes[m_MessageLabel[i]].StateAge=m_unJoiningLostPeriod
}
i=i+1
}
#Forget old information
i=0
while(i<size(m_vecNodes)){
if((m_vecNodes[i].StateAge>0) and (m_vecNodes[i].State=="ASSIGNING")){
m_vecNodes[i].StateAge=m_vecNodes[i].StateAge-1
if(m_vecNodes[i].StateAge==0)
m_vecNodes[i].State="UNASSIGNED"
}
i=i+1
}
}
#
#Transistion to state free
#
function TransitionToFree(){
UAVSTATE="STATE_FREE"
m_unWaitCount=m_unLabelSearchWaitTime
m_selfMessage.State=s2i(UAVSTATE)
}
#
#Transistion to state asking
#
function TransitionToAsking(un_label){
UAVSTATE="STATE_ASKING"
m_nLabel=un_label
m_unRequestId=id #don't know why the random numbers are the same, add id to make the ReqID different
m_selfMessage.State=s2i(UAVSTATE)
m_selfMessage.ReqLabel=m_nLabel
m_selfMessage.ReqID=m_unRequestId
m_unWaitCount=m_unResponseTimeThreshold
}
#
#Transistion to state joining
#
function TransitionToJoining(){
UAVSTATE="STATE_JOINING"
m_selfMessage.State=s2i(UAVSTATE)
m_selfMessage.Label=m_nLabel
m_unWaitCount=m_unJoiningLostPeriod
}
#
#Transistion to state joined
#
function TransitionToJoined(){
UAVSTATE="STATE_JOINED"
m_selfMessage.State=s2i(UAVSTATE)
m_selfMessage.Label=m_nLabel
m_vecNodes[m_nLabel].State="ASSIGNED"
#write statues
#v_tag.put(m_nLabel, m_lockstig)
barrier_create()
barrier_ready()
m_navigation.x=0.0
m_navigation.y=0.0
uav_moveto(m_navigation.x/100.0, m_navigation.y/100.0, 0.0)
}
#
#Transistion to state Lock, lock the current formation
#
function TransitionToLock(){
UAVSTATE="STATE_LOCK"
m_selfMessage.State=s2i(UAVSTATE)
m_selfMessage.Label=m_nLabel
m_vecNodes[m_nLabel].State="ASSIGNED"
#record neighbor distance
lock_neighbor_id={}
lock_neighbor_dis={}
var i=0
while(i<m_neighbourCount){
lock_neighbor_id[i]=m_messageID[i]
lock_neighbor_dis[i]=m_MessageRange[i]
i=i+1
}
m_navigation.x=0.0
m_navigation.y=0.0
uav_moveto(m_navigation.x, m_navigation.y, 0.0)
# prepare to restart a new shape
old_state = rc_State
#stop listening
neighbors.ignore("m")
}
#
# Do free
#
function DoFree() {
m_selfMessage.State=s2i(UAVSTATE)
#wait for a while before looking for a Label
if(m_unWaitCount>0)
m_unWaitCount=m_unWaitCount-1
#find a set of joined robots
var setJoinedLabels={}
var setJoinedIndexes={}
var i=0
var j=0
while(i<m_neighbourCount){
if(m_MessageState[i]=="STATE_JOINED"){
setJoinedLabels[j]=m_MessageLabel[i]
setJoinedIndexes[j]=i
j=j+1
}
i=i+1
}
#go through the graph to look for a proper Label
var unFoundLabel=0
# var IDofPred=0
i=1
while(i<size(m_vecNodes) and (unFoundLabel==0)){
#if the node is unassigned and the predecessor is insight
if(m_vecNodes[i].State=="UNASSIGNED" and count(setJoinedLabels,m_vecNodes[i].Pred)==1){
unFoundLabel=m_vecNodes[i].Label
# IDofPred=find(m_MessageLabel,m_vecNodes[unFoundLabel].Pred)
}
i=i+1
}
if(unFoundLabel>0){
TransitionToAsking(unFoundLabel)
return
}
#set message
m_selfMessage.State=s2i(UAVSTATE)
}
#
#Do asking
#
function DoAsking(){
#look for response from predecessor
var i=0
var psResponse=-1
while(i<m_neighbourCount and psResponse==-1){
#the respond robot in joined state
#the request Label be the same as requesed
#get a respond
if(m_MessageState[i]=="STATE_JOINED"){
#log("received label = ",m_MessageReqLabel[i])
if(m_MessageReqLabel[i]==m_nLabel)
if(m_MessageResponse[i]!="REQ_NONE"){
psResponse=i
}}
if(m_MessageState[i]=="STATE_JOINING" and m_MessageLabel[i]==m_nLabel){
TransitionToFree()
return
}
i=i+1
}
#analyse response
if(psResponse==-1){
#no response, wait
m_unWaitCount=m_unWaitCount-1
m_selfMessage.State=s2i(UAVSTATE)
m_selfMessage.ReqLabel=m_nLabel
m_selfMessage.ReqID=m_unRequestId
#if(m_unWaitCount==0){
#TransitionToFree()
#return
#}
}
else{
log("respond id=",m_MessageReqID[psResponse])
if(m_MessageReqID[psResponse]!=m_unRequestId){
m_vecNodes[m_nLabel].State="ASSIGNING"
m_vecNodes[m_nLabel].StateAge=m_unJoiningLostPeriod
TransitionToFree()
}
if(m_MessageReqID[psResponse]==m_unRequestId){
if(m_MessageResponse[psResponse]=="REQ_GRANTED"){
TransitionToJoining()
return
}
else{
TransitionToAsking(m_nLabel)
return
}
}
}
m_selfMessage.Label=m_nLabel
m_navigation.x=0.0
m_navigation.y=0.0
uav_moveto(m_navigation.x/100.0, m_navigation.y/100.0, 0.0)
}
#
#Do joining
#
function DoJoining(){
if(m_gotjoinedparent!=1)
set_rc_goto()
else
gotoWP(TransitionToJoined)
#pack the communication package
m_selfMessage.State=s2i(UAVSTATE)
m_selfMessage.Label=m_nLabel
}
function set_rc_goto() {
#get information of pred
var i=0
var IDofPred=-1
while(i<m_neighbourCount and IDofPred==-1){
if(m_MessageLabel[i]==m_vecNodes[m_nLabel].Pred and m_MessageState[i]=="STATE_JOINED")
IDofPred=i
i=i+1
}
#found pred
if(IDofPred!=-1){
m_unWaitCount=m_unJoiningLostPeriod#if see pred, reset the timer
var P2Target=math.vec2.newp(m_vecNodes[m_nLabel].distance,m_vecNodes[m_nLabel].bearing)
m_cMeToPred.Range=m_MessageRange[IDofPred]#the poition of self to pred in local coordinate
m_cMeToPred.Bearing=m_MessageBearing[IDofPred]
var S2Pred=math.vec2.newp(m_cMeToPred.Range,m_cMeToPred.Bearing)
var S2Target=math.vec2.add(S2Pred,P2Target)
goal = gps_from_vec(math.vec2.newp(math.vec2.length(S2Target)/100.0, math.atan(S2Target.y,S2Target.x)))
print("Saving GPS goal: ",goal.latitude, goal.longitude)
uav_storegoal(goal.latitude, goal.longitude, position.altitude)
m_gotjoinedparent = 1
}
}
#
#Do joined
#
function DoJoined(){
m_selfMessage.State=s2i(UAVSTATE)
m_selfMessage.Label=m_nLabel
#collect all requests
var mapRequests={}
var i=0
var j=0
var ReqLabel
var JoiningLabel
var seenPred=0
while(i<m_neighbourCount){
if(m_MessageState[i]=="STATE_ASKING"){
ReqLabel=m_MessageReqLabel[i]
#log("ReqLabel var:",ReqLabel)
#log("M_vec var",m_vecNodes[ReqLabel].State)
if(m_vecNodes[ReqLabel].State=="UNASSIGNED")
if(m_nLabel==m_vecNodes[ReqLabel].Pred){
#is a request, store the index
mapRequests[j]=i
j=j+1
}
}
if(m_MessageState[i]=="STATE_JOINING"){
JoiningLabel=m_MessageLabel[i]
if(m_nLabel==m_vecNodes[JoiningLabel].Pred){
##joining wrt this dot,send the global bearing
var m_messageForJoining={.Label=JoiningLabel,.Bearing=m_MessageBearing[i]-m_bias}
}
}
if(m_MessageState[i]=="STATE_JOINING" and repeat_assign==1 and m_MessageLabel[i]==assign_label){
repeat_assign=0
}
#if it is the pred
if((m_MessageState[i]=="STATE_JOINED" or m_MessageState[i]=="STATE_LOCK") and m_MessageLabel[i]==m_vecNodes[m_nLabel].Pred){
seenPred=1
m_unWaitCount=m_unJoiningLostPeriod
}
i=i+1
}
#get request
if(size(mapRequests)!=0){
i=1
var ReqIndex=0
while(i<size(mapRequests)){
#compare the distance
if(m_MessageRange[mapRequests[ReqIndex]]>m_MessageRange[mapRequests[i]])
ReqIndex=i
i=i+1
}
if(repeat_assign==0){
#get the best index, whose ReqLabel and Reqid are
ReqLabel=m_MessageReqLabel[mapRequests[ReqIndex]]
var ReqID=m_MessageReqID[mapRequests[ReqIndex]]
assign_label=ReqLabel
assign_id=ReqID
repeat_assign=1
}
m_selfMessage.ReqLabel=assign_label
m_selfMessage.ReqID=assign_id
m_selfMessage.Response=r2i("REQ_GRANTED")
#m_vecNodes[ReqLabel].State="ASSIGNING"
log("Label=",assign_label)
log("ID=",assign_id)
m_vecNodes[ReqLabel].StateAge=m_unJoiningLostPeriod
}
#lost pred, wait for some time and transit to free
if(seenPred==0){
m_unWaitCount=m_unWaitCount-1
if(m_unWaitCount==0){
TransitionToFree()
return
}
}
#check if should to transists to lock
#write statues
#v_tag.get(m_nLabel)
#log(v_tag.size(), " of ", ROBOTS, " ready to lock")
#if(v_tag.size()==ROBOTS){
# TransitionToLock()
#}
barrier_wait(ROBOTS, TransitionToLock, DoJoined, -1)
}
#
#Do Lock
#
function DoLock(){
m_selfMessage.State=s2i(UAVSTATE)
m_selfMessage.Label=m_nLabel
m_navigation.x=0.0
m_navigation.y=0.0
#calculate motion vection
if(m_nLabel==0){
m_navigation.x=0.0 #change value so that robot 0 will move
m_navigation.y=0.0
}
if(m_nLabel!=0){
m_navigation=motion_vector()
}
#move
uav_moveto(m_navigation.x, m_navigation.y, 0.0)
}
#
# Executed after takeoff
#
function action(){
statef=action
UAVSTATE="STATE_FREE"
# reset the graph
Reset()
}
#
# Executed at init
#
function init() {
#
# Global parameters for graph formation
#
m_unResponseTimeThreshold=10
m_unLabelSearchWaitTime=10
m_fTargetDistanceTolerance=100
m_fTargetAngleTolerance=0.1
m_unJoiningLostPeriod=100
#
# Join Swarm
#
uav_initswarm()
#v_tag = stigmergy.create(m_lockstig)
#uav_initstig()
# go to diff. height since no collision avoidance implemented yet
#TARGET_ALTITUDE = 20.0 + id * 2.5
statef=turnedoff
UAVSTATE = "TURNEDOFF"
}
#
# Executed every step (main loop)
#
function step() {
# listen to potential RC
uav_rccmd()
# get the swarm commands
uav_neicmd()
# update the vstig (status/net/batt)
#uav_updatestig()
#update the graph
UpdateNodeInfo()
#reset message package to be sent
m_selfMessage={.State=s2i("STATE_FREE"),.Label=0,.ReqLabel=0,.ReqID=0,.Response=r2i("REQ_NONE")}
#
# graph state machine
#
if(UAVSTATE=="STATE_FREE")
statef=DoFree
else if(UAVSTATE=="STATE_ASKING")
statef=DoAsking
else if(UAVSTATE=="STATE_JOINING")
statef=DoJoining
else if(UAVSTATE=="STATE_JOINED")
statef=DoJoined
else if(UAVSTATE=="STATE_LOCK" and old_state!=rc_State)
statef=action
else if(UAVSTATE=="STATE_LOCK" and old_state==rc_State)
statef=DoLock
# high level UAV state machine
statef()
log("Current state: ", UAVSTATE, " and label: ", m_nLabel)
log("Swarm size: ", ROBOTS)
#navigation
#broadcast message
neighbors.broadcast("m",packmessage(m_selfMessage))
#
#clean message storage
m_MessageState={}#store received neighbour message
m_MessageLabel={}#store received neighbour message
m_MessageReqLabel={}#store received neighbour message
m_MessageReqID={}#store received neighbour message
m_MessageResponse={}#store received neighbour message
m_MessageRange={}#store received neighbour message
m_MessageBearing={}#store received neighbour message
m_neighbourCount=0
}
#
# Executed when reset
#
function Reset(){
m_receivedMessage={.State=s2i("STATE_FREE"),.Label=0,.ReqLabel=0,.ReqID=0,.Response=r2i("REQ_NONE"),.Range=0,.Bearing=0}
m_selfMessage={.State=s2i("STATE_FREE"),.Label=0,.ReqLabel=0,.ReqID=0,.Response=r2i("REQ_NONE")}
m_navigation={.x=0,.y=0}
m_nLabel=-1
m_messageID={}
lock_neighbor_id={}
lock_neighbor_dis={}
m_unRequestId=0
m_bias=0
m_cMeToPred={.Range=0.0,.Bearing=0.0,.GlobalBearing=0.0}
m_unWaitCount=0
repeat_assign=0
assign_label=-1
assign_id=-1
m_gotjoinedparent = 0
if(rc_State==0){
log("Loading P graph")
Read_GraphP()
} else if(rc_State==1) {
log("Loading O graph")
Read_GraphO()
} else if(rc_State==2) {
log("Loading L graph")
Read_GraphL()
} else if(rc_State==3) {
log("Loading Y graph")
Read_GraphY()
}
#start listening
start_listen()
#
#set initial state, only one robot choose [A], while the rest choose [B]
#
#[A]The robot used to triger the formation process is defined as joined,
if(id==ROOT_ID){
m_nLabel=0
TransitionToJoined()
}
#[B]Other robots are defined as free.
else{
TransitionToFree()
}
}
#
# Executed upon destroy
#
function destroy() {
#clear neighbour message
m_navigation.x=0.0
m_navigation.y=0.0
uav_moveto(m_navigation.x/100.0, m_navigation.y/100.0, 0.0)
m_vecNodes={}
#stop listening
neighbors.ignore("m")
}

View File

@ -7,49 +7,73 @@
# #
# Constants # Constants
# #
BARRIER_VSTIG = 11 BARRIER_TIMEOUT = 1200 # in steps
BARRIER_VSTIG = 80
timeW = 0
barrier = nil
# #
# Sets a barrier # Sets a barrier
# #
function barrier_set(threshold, transf, resumef) { function barrier_create() {
statef = function() { # reset
barrier_wait(threshold, transf, resumef); timeW = 0
# create barrier vstig
#log("---> Prev. br. ", barrier, " ", BARRIER_VSTIG)
if(barrier!=nil) {
barrier=nil
BARRIER_VSTIG = BARRIER_VSTIG +1
} }
#log("---> New. br. ", barrier, " ", BARRIER_VSTIG)
barrier = stigmergy.create(BARRIER_VSTIG) barrier = stigmergy.create(BARRIER_VSTIG)
} }
function barrier_set(threshold, transf, resumef, bdt) {
statef = function() {
barrier_wait(threshold, transf, resumef, bdt);
}
UAVSTATE = "BARRIERWAIT"
barrier_create()
}
# #
# Make yourself ready # Make yourself ready
# #
function barrier_ready() { function barrier_ready() {
#log("BARRIER READY -------")
barrier.put(id, 1) barrier.put(id, 1)
barrier.put("d", 0)
} }
# #
# Executes the barrier # Executes the barrier
# #
BARRIER_TIMEOUT = 200 function barrier_wait(threshold, transf, resumef, bdt) {
timeW=0
function barrier_wait(threshold, transf, resumef) {
barrier.get(id)
barrier.put(id, 1) barrier.put(id, 1)
UAVSTATE = "BARRIERWAIT"
if(barrier.size() >= threshold) { barrier.get(id)
# getlowest() #log("--->BS: ", barrier.size(), " (", BARRIER_VSTIG, ")")
if(barrier.size() - 1 >= threshold or barrier.get("d") == 1) {
barrier.put("d", 1)
timeW = 0
transf() transf()
} else if(timeW>=BARRIER_TIMEOUT) { } else if(timeW >= BARRIER_TIMEOUT) {
barrier = nil log("------> Barrier Timeout !!!!")
barrier=nil
timeW = 0
resumef() resumef()
timeW=0
} }
if(bdt!=-1)
neighbors.broadcast("cmd", bdt)
timeW = timeW+1 timeW = timeW+1
} }
# get the lowest id of the fleet, but requires too much bandwidth # get the lowest id of the fleet, but requires too much bandwidth...
function getlowest(){ function getlowest(){
Lid = 20; Lid = 15;
u=20 u=15
while(u>=0){ while(u>=0){
tab = barrier.get(u) tab = barrier.get(u)
if(tab!=nil){ if(tab!=nil){
@ -59,4 +83,4 @@ function getlowest(){
u=u-1 u=u-1
} }
log("--> LOWEST ID:",Lid) log("--> LOWEST ID:",Lid)
} }

View File

@ -1,7 +1,7 @@
#Table of the nodes in the graph #Table of the nodes in the graph
m_vecNodes={} m_vecNodes={}
function Read_Graph(){ function Read_GraphL(){
m_vecNodes[0] = { # The .graph file is stored according the sequence of Label, predecessor, distance, bearing m_vecNodes[0] = { # The .graph file is stored according the sequence of Label, predecessor, distance, bearing
.Label = 0, # Label of the point .Label = 0, # Label of the point
.Pred = -1, # Label of its predecessor .Pred = -1, # Label of its predecessor

View File

@ -1,7 +1,7 @@
#Table of the nodes in the graph #Table of the nodes in the graph
m_vecNodes={} m_vecNodes={}
m_vecNodes_fixed={}
function Read_Graph(){ function Read_GraphO(){
m_vecNodes[0] = { # The .graph file is stored according the sequence of Label, predecessor, distance, bearing m_vecNodes[0] = { # The .graph file is stored according the sequence of Label, predecessor, distance, bearing
.Label = 0, # Label of the point .Label = 0, # Label of the point
.Pred = -1, # Label of its predecessor .Pred = -1, # Label of its predecessor

View File

@ -1,7 +1,7 @@
#Table of the nodes in the graph #Table of the nodes in the graph
m_vecNodes={} m_vecNodes={}
m_vecNodes_fixed={}
function Read_Graph(){ function Read_GraphP(){
m_vecNodes[0] = { # The .graph file is stored according the sequence of Label, predecessor, distance, bearing m_vecNodes[0] = { # The .graph file is stored according the sequence of Label, predecessor, distance, bearing
.Label = 0, # Label of the point .Label = 0, # Label of the point
.Pred = -1, # Label of its predecessor .Pred = -1, # Label of its predecessor
@ -14,7 +14,7 @@ m_vecNodes[0] = { # The .graph file is stored according the sequence of Lab
m_vecNodes[1] = { m_vecNodes[1] = {
.Label = 1, .Label = 1,
.Pred = 0, .Pred = 0,
.distance = 2000, .distance = 1000,
.bearing = 0.0, .bearing = 0.0,
.height = 5000, .height = 5000,
.State="UNASSIGNED", .State="UNASSIGNED",
@ -23,7 +23,7 @@ m_vecNodes[1] = {
m_vecNodes[2] = { m_vecNodes[2] = {
.Label = 2, .Label = 2,
.Pred = 0, .Pred = 0,
.distance = 2000, .distance = 1000,
.bearing = 1.57, .bearing = 1.57,
.height = 7000, .height = 7000,
.State="UNASSIGNED", .State="UNASSIGNED",
@ -32,7 +32,7 @@ m_vecNodes[2] = {
m_vecNodes[3] = { m_vecNodes[3] = {
.Label = 3, .Label = 3,
.Pred = 0, .Pred = 0,
.distance = 2000, .distance = 1000,
.bearing = 4.71, .bearing = 4.71,
.height = 9000, .height = 9000,
.State="UNASSIGNED", .State="UNASSIGNED",
@ -41,7 +41,7 @@ m_vecNodes[3] = {
m_vecNodes[4] = { m_vecNodes[4] = {
.Label = 4, .Label = 4,
.Pred = 1, .Pred = 1,
.distance = 1414, .distance = 707,
.bearing = 0.79, .bearing = 0.79,
.height = 11000, .height = 11000,
.State="UNASSIGNED", .State="UNASSIGNED",
@ -50,7 +50,7 @@ m_vecNodes[4] = {
m_vecNodes[5] = { m_vecNodes[5] = {
.Label = 5, .Label = 5,
.Pred = 2, .Pred = 2,
.distance = 2000, .distance = 1000,
.bearing = 0.0, .bearing = 0.0,
.height = 14000, .height = 14000,
.State="UNASSIGNED", .State="UNASSIGNED",

View File

@ -1,7 +1,7 @@
#Table of the nodes in the graph #Table of the nodes in the graph
m_vecNodes={} m_vecNodes={}
m_vecNodes_fixed={}
function Read_Graph(){ function Read_GraphY(){
m_vecNodes[0] = { # The .graph file is stored according the sequence of Label, predecessor, distance, bearing m_vecNodes[0] = { # The .graph file is stored according the sequence of Label, predecessor, distance, bearing
.Label = 0, # Label of the point .Label = 0, # Label of the point
.Pred = -1, # Label of its predecessor .Pred = -1, # Label of its predecessor

View File

@ -0,0 +1,89 @@
0,-73.1531935978886,45.5084960903092,15,15
1,-73.1530989420915,45.5085624255498,15,15
2,-73.1530042862771,45.5086287608025,15,15
3,-73.1529096304626,45.5086950960552,15,15
4,-73.1529458247399,45.5087204611798,15,15
5,-73.1530404805543,45.5086541259271,15,15
6,-73.1531351363515,45.5085877906865,15,15
7,-73.1532297921486,45.508521455446,15,15
8,-73.1533244479457,45.5084551202054,15,15
9,-73.1533606422273,45.508480485333,15,15
10,-73.1532659864302,45.5085468205736,15,15
11,-73.153171330633,45.5086131558142,15,15
12,-73.1530766748359,45.5086794910548,15,15
13,-73.1529820190215,45.5087458263075,15,15
14,-73.1530182132901,45.5087711914261,15,15
15,-73.1531128691045,45.5087048561733,15,15
16,-73.1532075249016,45.5086385209327,15,15
17,-73.1533021806988,45.5085721856922,15,15
18,-73.1533968364959,45.5085058504516,15,15
19,-73.1534330307645,45.5085312155701,15,15
20,-73.1533383749674,45.5085975508107,15,15
21,-73.1532437191702,45.5086638860513,15,15
22,-73.1531490633731,45.5087302212919,15,15
23,-73.1530544075587,45.5087965565446,15,15
24,-73.1530906018273,45.5088219216632,15,15
25,-73.1531852576417,45.5087555864105,15,15
26,-73.1532799134389,45.5086892511699,15,15
27,-73.153374569236,45.5086229159293,15,15
28,-73.1534692250331,45.5085565806887,15,15
29,-73.1535054193017,45.5085819458072,15,15
30,-73.1534107635046,45.5086482810478,15,15
31,-73.1533161077075,45.5087146162884,15,15
32,-73.1532214519103,45.508780951529,15,15
33,-73.1531267960959,45.5088472867817,15,15
34,-73.1531629903645,45.5088726519003,15,15
35,-73.1532576461789,45.5088063166476,15,15
36,-73.1533523019761,45.508739981407,15,15
37,-73.1534469577732,45.5086736461664,15,15
38,-73.1535416135703,45.5086073109258,15,15
39,-73.1535778078389,45.5086326760444,15,15
40,-73.1534831520418,45.5086990112849,15,15
41,-73.1533884962447,45.5087653465255,15,15
42,-73.1532938404476,45.5088316817661,15,15
43,-73.1531991846331,45.5088980170188,15,15
44,-73.1532353789017,45.5089233821374,15,15
45,-73.1533300347162,45.5088570468847,15,15
46,-73.1534246905133,45.5087907116441,15,15
47,-73.1535193463104,45.5087243764035,15,15
48,-73.1536140021075,45.5086580411629,15,15
49,-73.1536501963762,45.5086834062815,15,15
50,-73.153555540579,45.508749741522,15,15
51,-73.1534608847819,45.5088160767626,15,15
52,-73.1533662289848,45.5088824120032,15,15
53,-73.1532715731703,45.508948747256,15,15
54,-73.1533077674389,45.5089741123745,15,15
55,-73.1534024232534,45.5089077771218,15,15
56,-73.1534970790505,45.5088414418812,15,15
57,-73.1535917348476,45.5087751066406,15,15
58,-73.1536863906448,45.5087087714,15,15
59,-73.1537225849134,45.5087341365186,15,15
60,-73.1536279291163,45.5088004717592,15,15
61,-73.1535332733191,45.5088668069997,15,15
62,-73.153438617522,45.5089331422403,15,15
63,-73.1533439617076,45.5089994774931,15,15
64,-73.1533801559762,45.5090248426116,15,15
65,-73.1534748117906,45.5089585073589,15,15
66,-73.1535694675877,45.5088921721183,15,15
67,-73.1536641233849,45.5088258368777,15,15
68,-73.153758779182,45.5087595016371,15,15
69,-73.1537949734506,45.5087848667557,15,15
70,-73.1537003176535,45.5088512019963,15,15
71,-73.1536056618563,45.5089175372369,15,15
72,-73.1535110060592,45.5089838724775,15,15
73,-73.1534163502448,45.5090502077302,15,15
74,-73.1534525445134,45.5090755728487,15,15
75,-73.1535472003278,45.509009237596,15,15
76,-73.1536418561249,45.5089429023554,15,15
77,-73.1537365119221,45.5088765671148,15,15
78,-73.1538311677192,45.5088102318742,15,15
79,-73.1538673619878,45.5088355969928,15,15
80,-73.1537727061907,45.5089019322334,15,15
81,-73.1536780503936,45.508968267474,15,15
82,-73.1535833945964,45.5090346027146,15,15
83,-73.153488738782,45.5091009379673,15,15
84,-73.1535249330852,45.5091263031101,15,15
85,-73.1536195888996,45.5090599678574,15,15
86,-73.1537142446968,45.5089936326168,15,15
87,-73.1538089004939,45.5089272973762,15,15
88,-73.153903556291,45.5088609621356,15,15
1 0 -73.1531935978886 45.5084960903092 15 15
2 1 -73.1530989420915 45.5085624255498 15 15
3 2 -73.1530042862771 45.5086287608025 15 15
4 3 -73.1529096304626 45.5086950960552 15 15
5 4 -73.1529458247399 45.5087204611798 15 15
6 5 -73.1530404805543 45.5086541259271 15 15
7 6 -73.1531351363515 45.5085877906865 15 15
8 7 -73.1532297921486 45.508521455446 15 15
9 8 -73.1533244479457 45.5084551202054 15 15
10 9 -73.1533606422273 45.508480485333 15 15
11 10 -73.1532659864302 45.5085468205736 15 15
12 11 -73.153171330633 45.5086131558142 15 15
13 12 -73.1530766748359 45.5086794910548 15 15
14 13 -73.1529820190215 45.5087458263075 15 15
15 14 -73.1530182132901 45.5087711914261 15 15
16 15 -73.1531128691045 45.5087048561733 15 15
17 16 -73.1532075249016 45.5086385209327 15 15
18 17 -73.1533021806988 45.5085721856922 15 15
19 18 -73.1533968364959 45.5085058504516 15 15
20 19 -73.1534330307645 45.5085312155701 15 15
21 20 -73.1533383749674 45.5085975508107 15 15
22 21 -73.1532437191702 45.5086638860513 15 15
23 22 -73.1531490633731 45.5087302212919 15 15
24 23 -73.1530544075587 45.5087965565446 15 15
25 24 -73.1530906018273 45.5088219216632 15 15
26 25 -73.1531852576417 45.5087555864105 15 15
27 26 -73.1532799134389 45.5086892511699 15 15
28 27 -73.153374569236 45.5086229159293 15 15
29 28 -73.1534692250331 45.5085565806887 15 15
30 29 -73.1535054193017 45.5085819458072 15 15
31 30 -73.1534107635046 45.5086482810478 15 15
32 31 -73.1533161077075 45.5087146162884 15 15
33 32 -73.1532214519103 45.508780951529 15 15
34 33 -73.1531267960959 45.5088472867817 15 15
35 34 -73.1531629903645 45.5088726519003 15 15
36 35 -73.1532576461789 45.5088063166476 15 15
37 36 -73.1533523019761 45.508739981407 15 15
38 37 -73.1534469577732 45.5086736461664 15 15
39 38 -73.1535416135703 45.5086073109258 15 15
40 39 -73.1535778078389 45.5086326760444 15 15
41 40 -73.1534831520418 45.5086990112849 15 15
42 41 -73.1533884962447 45.5087653465255 15 15
43 42 -73.1532938404476 45.5088316817661 15 15
44 43 -73.1531991846331 45.5088980170188 15 15
45 44 -73.1532353789017 45.5089233821374 15 15
46 45 -73.1533300347162 45.5088570468847 15 15
47 46 -73.1534246905133 45.5087907116441 15 15
48 47 -73.1535193463104 45.5087243764035 15 15
49 48 -73.1536140021075 45.5086580411629 15 15
50 49 -73.1536501963762 45.5086834062815 15 15
51 50 -73.153555540579 45.508749741522 15 15
52 51 -73.1534608847819 45.5088160767626 15 15
53 52 -73.1533662289848 45.5088824120032 15 15
54 53 -73.1532715731703 45.508948747256 15 15
55 54 -73.1533077674389 45.5089741123745 15 15
56 55 -73.1534024232534 45.5089077771218 15 15
57 56 -73.1534970790505 45.5088414418812 15 15
58 57 -73.1535917348476 45.5087751066406 15 15
59 58 -73.1536863906448 45.5087087714 15 15
60 59 -73.1537225849134 45.5087341365186 15 15
61 60 -73.1536279291163 45.5088004717592 15 15
62 61 -73.1535332733191 45.5088668069997 15 15
63 62 -73.153438617522 45.5089331422403 15 15
64 63 -73.1533439617076 45.5089994774931 15 15
65 64 -73.1533801559762 45.5090248426116 15 15
66 65 -73.1534748117906 45.5089585073589 15 15
67 66 -73.1535694675877 45.5088921721183 15 15
68 67 -73.1536641233849 45.5088258368777 15 15
69 68 -73.153758779182 45.5087595016371 15 15
70 69 -73.1537949734506 45.5087848667557 15 15
71 70 -73.1537003176535 45.5088512019963 15 15
72 71 -73.1536056618563 45.5089175372369 15 15
73 72 -73.1535110060592 45.5089838724775 15 15
74 73 -73.1534163502448 45.5090502077302 15 15
75 74 -73.1534525445134 45.5090755728487 15 15
76 75 -73.1535472003278 45.509009237596 15 15
77 76 -73.1536418561249 45.5089429023554 15 15
78 77 -73.1537365119221 45.5088765671148 15 15
79 78 -73.1538311677192 45.5088102318742 15 15
80 79 -73.1538673619878 45.5088355969928 15 15
81 80 -73.1537727061907 45.5089019322334 15 15
82 81 -73.1536780503936 45.508968267474 15 15
83 82 -73.1535833945964 45.5090346027146 15 15
84 83 -73.153488738782 45.5091009379673 15 15
85 84 -73.1535249330852 45.5091263031101 15 15
86 85 -73.1536195888996 45.5090599678574 15 15
87 86 -73.1537142446968 45.5089936326168 15 15
88 87 -73.1538089004939 45.5089272973762 15 15
89 88 -73.153903556291 45.5088609621356 15 15

View File

@ -0,0 +1,151 @@
# Write to matrix
robot_marker = "X"
function wmat(mat, row, col, val) {
var index = (row-1)*mat.nb_col + (col - 1)
if( row <= mat.nb_row) { # update val
mat.mat[index] = val
} else if(row == mat.nb_row + 1){ # add entry
mat.nb_row = mat.nb_row + 1
mat.mat[index] = val
}
}
# Read from matrix
function rmat(mat, row, col) {
#log("rmat ", mat, row, col)
index = (row-1)*mat.nb_col + (col - 1)
if (mat.mat[index] == nil) {
log("Wrong matrix read index: ", row, " ", col)
return -1
} else {
return mat.mat[index]
}
}
# copy a full matrix row
function mat_copyrow(out,ro,in,ri){
var indexI = (ri-1)*in.nb_col
var indexO = (ro-1)*out.nb_col
icr=0
while(icr<in.nb_col){
out.mat[indexO+icr]=in.mat[indexI+icr]
icr = icr + 1
}
}
function getvec(t,row){
return math.vec2.new(rmat(t,row,1),rmat(t,row,2))
}
function init_test_map(len){
map = {.nb_col=len, .nb_row=len, .mat={}}
index = 0
while(index<len*len){
map.mat[index]=1.0
index = index + 1
}
# puts an obstacle right in the middle
wmat(map,5,5,0.0)
wmat(map,6,5,0.0)
wmat(map,4,5,0.0)
log("Occupancy grid initialized (",len,"x",len,") with obstacles.")
}
function init_map(len){
map = {.nb_col=len, .nb_row=len, .mat={}}
index = 0
while(index<len*len){
map.mat[index]=1.0
index = index + 1
}
log("Occupancy grid initialized (",len,"x",len,").")
}
function add_obstacle(pos, off, inc_trust) {
xi = math.round(pos.x)
yi = math.round(pos.y)
if(xi < map.nb_col+1 and yi < map.nb_row+1 and xi > 0 and yi > 0) {
#log("Add obstacle in cell: ", xi, " ", yi)
old=rmat(map,xi,yi)
if(old-inc_trust > 0.0)
wmat(map,xi,yi,old-inc_trust)
else
wmat(map,xi,yi,0.0)
}
}
function remove_obstacle(pos, off, dec_trust) {
xi = math.round(pos.x)
yi = math.round(pos.y)
if(xi < map.nb_col+1 and yi < map.nb_row+1 and xi > 0 and yi > 0){
#log("Remove obstacle in cell: ", xi, " ", yi)
old=rmat(map, xi, yi)
if(old + dec_trust < 1.0) #x,y
wmat(map, xi, yi, old+dec_trust)
else
wmat(map, xi, yi, 1.0)
}
}
function table_print(t) {
foreach(t, function(key, value) {
log(key, " -> ", value)
})
}
function table_copy(t) {
var t2 = {}
foreach(t, function(key, value) {
t2[key] = value
})
return t2
}
function print_pos(t) {
ir=1
while(ir<=t.nb_row){
log(ir, ": ", rmat(t,ir,1), " ", rmat(t,ir,2))
ir = ir + 1
}
}
function print_map(t) {
ir=t.nb_row
log("Printing a ", t.nb_row, " by ", t.nb_col, " map")
while(ir>0){
logst=string.concat("\t", string.tostring(ir), "\t:")
ic=t.nb_col
while(ic>0){
if(ir==cur_cell.x and ic==cur_cell.y)
logst = string.concat(logst, " XXXXXXXX")
else
logst = string.concat(logst, " ", string.tostring(rmat(t,ir,ic)))
ic = ic - 1
}
log(logst)
ir = ir - 1
}
}
function print_map_argos(t){
ir=t.nb_row
msg = string.tostring(ir)
while(ir>0){
ic=t.nb_col
while(ic>0){
if(ir==cur_cell.x and ic==cur_cell.y){
msg = string.concat(msg, ":", robot_marker)
}
else {
msg = string.concat(msg, ":", string.tostring(rmat(t,ir,ic)))
}
ic = ic - 1
}
ir = ir - 1
}
set_argos_map(msg)
}

View File

@ -0,0 +1,454 @@
#####
# RRT* Path Planing
#
# map table-based matrix
#####
include "mapmatrix.bzz"
RRT_TIMEOUT = 500
map = nil
cur_cell = {}
nei_cell = {}
function UAVinit_map(m_navigation) {
# create a map big enough for the goal
init_map(2*math.round(math.vec2.length(m_navigation))+10)
# center the robot on the grid
cur_cell = math.vec2.new(math.round(map.nb_col/2.0),math.round(map.nb_row/2.0))
}
function UAVpathPlanner(m_navigation, m_pos) {
# place the robot on the grid
update_curcell(m_pos,0)
# create the goal in the map grid
mapgoal = math.vec2.add(m_navigation,cur_cell)
mapgoal = math.vec2.new(math.round(mapgoal.x),math.round(mapgoal.y))
# search for a path
return RRTSTAR(mapgoal,math.vec2.new(5,5)) #map.nb_col/20.0,map.nb_row/20.0))
}
function Kh4pathPlanner(m_goal, m_pos) {
# move 0,0 to a corner instead of the center
m_goal = math.vec2.sub(m_goal,math.vec2.new(GRIDCM.xmin, GRIDCM.ymin))
m_goal = math.vec2.new(math.round(m_goal.x*CM2KH4.x), math.round(m_goal.y*CM2KH4.y))
# place the robot on the grid
update_curcell(m_pos,1)
log("Starting from cell: ", cur_cell.x, " ", cur_cell.y)
log("Going to cell: ", m_goal.x, " ", m_goal.y)
# search for a path
print_map(map)
# print_map_argos(map)
return RRTSTAR(m_goal, math.vec2.new(10.0 * CM2KH4.x, 10.0 * CM2KH4.y))
}
function update_curcell(m_curpos, kh4) {
if(kh4) { # for khepera playground
cur_cell = math.vec2.sub(m_curpos, math.vec2.new(GRIDCM.xmin, GRIDCM.ymin))
cur_cell = math.vec2.new(math.round(cur_cell.x*CM2KH4.x), math.round(cur_cell.y*CM2KH4.y))
} else { # for uav map relative to home
cur_cell = math.vec2.add(cur_cell, m_curpos)
cur_cell = math.vec2.new(math.round(m_curpos.x), math.round(m_curpos.y))
}
if(cur_cell.x>map.nb_row)
cur_cell.x=map.nb_row
if(cur_cell.y>map.nb_col)
cur_cell.y=map.nb_col
if(cur_cell.x<1)
cur_cell.x=1
if(cur_cell.y<1)
cur_cell.y=1
}
function UAVgetneiobs (m_curpos) {
update_curcell(m_curpos,0)
# add all neighbors as obstacles in the grid
neighbors.foreach(function(rid, data) {
add_obstacle(math.vec2.add(math.vec2.newp(data.distance,data.azimuth),cur_cell), 0, 1.0)
})
}
function getneiobs (m_curpos) {
foundobstacle = 0
update_curcell(m_curpos,1)
old_nei = table_copy(nei_cell)
#log("NeiObs debug: ", nei_cell[9], " ", nei_cell[3])
neighbors.foreach(function(rid, data) {
#log("nei rel pos: ", data.distance, "m ", data.azimuth*180.0/math.pi, "deg")
Ncell = math.vec2.add(math.vec2.newp(data.distance*100,data.azimuth + absolute_position.theta), m_curpos)
#log("nei abs pos: ", Ncell.x, "cm ", Ncell.y, "cm")
Ncell = math.vec2.sub(Ncell, math.vec2.new(GRIDCM.xmin, GRIDCM.ymin))
Ncell = math.vec2.new(math.round(Ncell.x*CM2KH4.x), math.round(Ncell.y*CM2KH4.y))
nei_cell[rid] = {.x=Ncell.x, .y=Ncell.y}
#log("Neighbor in : ", Ncell.x, " ", Ncell.y)
if(old_nei[rid]!=nil) {
if(old_nei[rid].x!=nei_cell[rid].x or old_nei[rid].y!=nei_cell[rid].y) {
#log("Neighbor moved ! ", nei_cell[rid].x, " ", nei_cell[rid].y)
remove_obstacle(math.vec2.new(old_nei[rid].x, old_nei[rid].y), 0, 1)
remove_obstacle(math.vec2.new(old_nei[rid].x+1, old_nei[rid].y), 0, 1)
remove_obstacle(math.vec2.new(old_nei[rid].x-1, old_nei[rid].y), 0, 1)
remove_obstacle(math.vec2.new(old_nei[rid].x, old_nei[rid].y+1), 0, 1)
remove_obstacle(math.vec2.new(old_nei[rid].x, old_nei[rid].y-1), 0, 1)
add_obstacle(Ncell, 0, 1.0)
add_obstacle(math.vec2.new(Ncell.x+1, Ncell.y), 0, 1.0)
add_obstacle(math.vec2.new(Ncell.x-1, Ncell.y), 0, 1.0)
add_obstacle(math.vec2.new(Ncell.x, Ncell.y+1), 0, 1.0)
add_obstacle(math.vec2.new(Ncell.x, Ncell.y-1), 0, 1.0)
foundobstacle = 1
}
} else {
add_obstacle(Ncell, 0, 1.0)
add_obstacle(math.vec2.new(Ncell.x+1, Ncell.y), 0, 1.0)
add_obstacle(math.vec2.new(Ncell.x-1, Ncell.y), 0, 1.0)
add_obstacle(math.vec2.new(Ncell.x, Ncell.y+1), 0, 1.0)
add_obstacle(math.vec2.new(Ncell.x, Ncell.y-1), 0, 1.0)
foundobstacle = 1
}
})
#if(foundobstacle) {
#print_map(map)
#}
return foundobstacle
}
function getproxobs (m_curpos) {
foundobstacle = 0
update_curcell(m_curpos,1)
reduce(proximity,
function(key, value, acc) {
obs = math.vec2.add(math.vec2.newp(1.15, value.angle * math.pi / 180.0 + absolute_position.theta), cur_cell)
obs2 = math.vec2.add(math.vec2.newp(2.15, value.angle * math.pi / 180.0 + absolute_position.theta), cur_cell)
per = math.vec2.sub(obs,cur_cell)
obsr = math.vec2.add(math.vec2.newp(1.25, math.vec2.angle(per) + math.pi/2.0), obs)
obsr2 = math.vec2.add(math.vec2.newp(1.25, math.vec2.angle(per) + math.pi/2.0), obs2)
obsl = math.vec2.add(math.vec2.newp(1.25, math.vec2.angle(per) - math.pi/2.0), obs)
obsl2 = math.vec2.add(math.vec2.newp(1.25, math.vec2.angle(per) - math.pi/2.0), obs2)
if(value.value > IR_SENSOR_THRESHOLD) {
if(rmat(map,math.round(obs.x),math.round(obs.y))!=0) {
add_obstacle(obs, 0, 0.25)
add_obstacle(obs2, 0, 0.25)
add_obstacle(obsr, 0, 0.25)
add_obstacle(obsr2, 0, 0.25)
add_obstacle(obsl, 0, 0.25)
add_obstacle(obsl2, 0, 0.25)
foundobstacle = 1
}
} else if(rmat(map,math.round(obs.x),math.round(obs.y))!=1) {
remove_obstacle(obs, 0, 0.05)
foundobstacle = 1
}
return acc
}, math.vec2.new(0, 0))
#if(foundobstacle) {
# reduce(proximity,
# function(key, value, acc){
# log(value.value, ", ", value.angle)
# return acc
# }, math.vec2.new(0, 0))
# print_map(map)
#}
return foundobstacle
}
function check_path(m_path, goal_l, m_curpos, kh4) {
pathisblocked = 0
nb=goal_l
update_curcell(m_curpos,kh4)
Cvec = cur_cell
while(nb < m_path.nb_row and nb <= goal_l+1){
Nvec = getvec(m_path, nb)
if(kh4==0)
Nvec=vec_from_gps(Nvec.x,Nvec.y)
if(doesItIntersect(Cvec, Nvec)){
log("Obstacle in the way ! (", Cvec.x, "/", Cvec.y, "->", Nvec.x, "/", Nvec.y, ")")
pathisblocked = 1
}
Cvec=Nvec
nb = nb + 1
}
return pathisblocked
}
function RRTSTAR(GOAL,TOL) {
HEIGHT = map.nb_col-1
WIDTH = map.nb_row-1
RADIUS = 1.25 #TOL.x #map.nb_col/10.0 # to consider 2 points consecutive
goalBoundary = {.xmin=GOAL.x-TOL.x, .xmax=GOAL.x+TOL.x, .ymin=GOAL.y-TOL.y, .ymax=GOAL.y+TOL.y}
#table_print(goalBoundary)
arrayOfPoints = {.nb_col=2, .nb_row=1, .mat={.0=cur_cell.x,.1=cur_cell.y}}
Path = {.nb_col=2, .nb_row=1, .mat={.0=cur_cell.x,.1=cur_cell.y}}
numberOfPoints = 1
Q = {.nb_col=5,.nb_row=1,.mat={.0=cur_cell.x,.1=cur_cell.y,.2=0,.3=1,.4=0}}
goalReached = 0;
timeout = 0
##
# main search loop
##
while(goalReached == 0 and timeout < RRT_TIMEOUT) {
# Point generation only as grid cell centers
pt = math.vec2.new(math.round(HEIGHT * math.rng.uniform(1.0) + 1), math.round(WIDTH * math.rng.uniform(1.0) + 1))
#log("Point generated: ", pt.x, " ", pt.y)
pointList = findPointsInRadius(pt,Q,RADIUS);
# Find connection that provides the least cost to come
nbCount = 0;
minCounted = 999;
minCounter = 0;
if(pointList.nb_row!=0) {
#log("Found ", pointList.nb_row, " close point:", pointList.mat)
ipt=1
while(ipt<=pointList.nb_row){
pointNumber = {.nb_col=pointList.nb_col, .nb_row=1, .mat={}}
mat_copyrow(pointNumber,1,pointList,ipt)
# Follow the line to see if it intersects anything
intersects = doesItIntersect(pt,getvec(pointNumber,1));
#log("intersects1: ", intersects)
# If there is no intersection we need consider its connection
nbCount = nbCount + 1;
if(intersects != 1) {
#log(pointNumber, "do not intersect (",pointNumber.mat[3],")")
distance = math.vec2.length(math.vec2.sub(getvec(pointNumber,1),pt))+rmat(Q,pointNumber.mat[3],5)
if(distance < minCounted) {
minCounted = distance;
minCounter = nbCount;
}
}
ipt = ipt + 1
}
if(minCounter > 0) {
numberOfPoints = numberOfPoints + 1;
wmat(arrayOfPoints,numberOfPoints,1,pt.x)
wmat(arrayOfPoints,numberOfPoints,2,pt.y)
wmat(Q,numberOfPoints,1, pt.x)
wmat(Q,numberOfPoints,2, pt.y)
wmat(Q,numberOfPoints,3, rmat(pointList,minCounter,4));
wmat(Q,numberOfPoints,4, numberOfPoints)
wmat(Q,numberOfPoints,5, minCounted)
#log("added point to Q(", Q.nb_row, "): ", pt.x, " ", pt.y)
# Now check to see if any of the other points can be redirected
nbCount = 0;
ipt = 1
while(ipt<pointList.nb_row) {
pointNumber = {.nb_col=pointList.nb_col, .nb_row=1, .mat={}}
mat_copyrow(pointNumber,1,pointList,ipt)
# Follow the line to see if it intersects anything
intersects = doesItIntersect(pt,getvec(pointNumber,1));
#log("intersects2: ", intersects)
# If there is no intersection we need consider its connection
nbCount = nbCount + 1;
if(intersects != 1) {
# If the alternative path is shorter than change it
tmpdistance = rmat(Q,numberOfPoints,5)+math.vec2.length(math.vec2.sub(getvec(pointNumber,1),pt))
if(tmpdistance < rmat(Q,rmat(pointNumber,1,4),5)) {
wmat(Q,rmat(pointNumber,1,4),3, numberOfPoints)
wmat(Q,rmat(pointNumber,1,4),5, tmpdistance)
}
}
ipt = ipt + 1
}
# Check to see if this new point is within the goal
if(pt.x < goalBoundary.xmax and pt.x > goalBoundary.xmin and pt.y > goalBoundary.ymin and pt.y < goalBoundary.ymax)
goalReached = 1;
}
} else {
# Associate with the closest point
pointNum = findClosestPoint(pt,arrayOfPoints);
# Follow the line to see if it intersects anything
intersects = doesItIntersect(pt,getvec(arrayOfPoints,pointNum));
#log("intersects3 (", pointNum, "): ", intersects)
# If there is no intersection we need to add to the tree
if(intersects != 1) {
numberOfPoints = numberOfPoints + 1;
wmat(arrayOfPoints,numberOfPoints,1,pt.x)
wmat(arrayOfPoints,numberOfPoints,2,pt.y)
wmat(Q,numberOfPoints,1, pt.x)
wmat(Q,numberOfPoints,2, pt.y)
wmat(Q,numberOfPoints,3, pointNum);
wmat(Q,numberOfPoints,4, numberOfPoints)
wmat(Q,numberOfPoints,5, rmat(Q,pointNum,5)+math.vec2.length(math.vec2.sub(getvec(Q,pointNum),pt)))
#log("added point to Q(", Q.nb_row, "): ", pt.x, " ", pt.y)
# Check to see if this new point is within the goal
if(pt.x < goalBoundary.xmax and pt.x > goalBoundary.xmin and pt.y > goalBoundary.ymin and pt.y < goalBoundary.ymax)
goalReached = 1;
}
}
if(numberOfPoints % 100 == 0) {
log(numberOfPoints, " points processed. Still looking for goal.");
}
timeout = timeout + 1
}
if(goalReached){
log("Goal found(",numberOfPoints,")!")
Path = getPathGPS(Q,numberOfPoints)
print_pos(Path)
} else {
log("FAILED TO FIND A PATH!!!")
Path = nil
}
return Path
}
function findClosestPoint(point,aPt) {
# Go through each points and find the distances between them and the
# target point
distance = 999
pointNumber = -1
ifcp=1
while(ifcp<=aPt.nb_row) {
range = math.vec2.length(math.vec2.sub(point,getvec(aPt,ifcp)))
if(range < distance) {
distance = range;
pointNumber = ifcp;
}
ifcp = ifcp + 1
}
return pointNumber
}
# Find the closest point in the tree
function findPointsInRadius(point,q,r) {
counted = 0;
pointList = {.nb_col=q.nb_col, .nb_row=counted, .mat={}}
iir=1
while(iir <= q.nb_row) {
tmpvv = getvec(q,iir)
#log("FPiR :", point.x, " ", point.y," ", tmpvv.x," ", tmpvv.y)
distance = math.vec2.length(math.vec2.sub(getvec(q,iir),point))
if(distance < r) {
counted = counted+1;
pointList.nb_row=counted
mat_copyrow(pointList,counted,q,iir)
}
iir = iir + 1
}
return pointList
}
# check if the line between 2 point intersect an obstacle
function doesItIntersect(point,vector) {
#log("DiI :", point.x, " ", point.y," ", vector.x," ", vector.y)
dif = math.vec2.sub(point,vector)
distance = math.vec2.length(dif)
if(distance==0.0){
# Find what block we're in right now
xi = math.round(point.x) #+1
yi = math.round(point.y) #+1
if(xi!=cur_cell.x and yi!=cur_cell.y){
if(rmat(map,xi,yi) > 0.5)
return 1
else
return 0
} else
return 0
}
vec = math.vec2.scale(dif,1.0/distance)
pathstep = map.nb_col - 2
idii = 1.0
while(idii <= pathstep) {
range = distance*idii/pathstep
pos_chk = math.vec2.sub(point,math.vec2.scale(vec,range));
# Find what block we're in right now
xi = math.round(pos_chk.x) #+1
yi = math.round(pos_chk.y) #+1
#log("Grid :", pos_chk.x, " ", pos_chk.y," ", xi," ", yi, " R: ", range)
if(xi!=cur_cell.x and yi!=cur_cell.y){
if(xi < map.nb_col+1 and yi < map.nb_row+1 and xi > 0 and yi > 0) {
if(rmat(map,xi,yi) < 0.5) { # because obstacle use trust values
#log("Obstacle in the way(", xi, " ", yi, ": ", rmat(map,xi,yi), ")!")
return 1;
}
} else {
#log("Outside the map(", xi, " ", yi, ")! ", range, "/", distance, " : ", pos_chk.x, " ", pos_chk.y, " : ", vec.x, " ", vec.y)
return 1;
}
}
idii = idii + 1.0
}
#log("No intersect!")
return 0
}
function getPathGPS(Q,nb){
path={.nb_col=2, .nb_row=0, .mat={}}
npt=0
# get the path from the point list
while(nb!=1){
npt=npt+1
path.nb_row=npt
path.mat[(npt-1)*2]=rmat(Q,nb,1)
path.mat[(npt-1)*2+1]=rmat(Q,nb,2)
nb = rmat(Q,nb,3);
}
# re-order the list and make the path points absolute
pathR={.nb_col=2, .nb_row=path.nb_row, .mat={}}
while(npt>0){
tmpgoal = gps_from_vec(math.vec2.sub(getvec(path,npt),cur_cell))
pathR.mat[(path.nb_row-npt)*2]=tmpgoal.latitude
pathR.mat[(path.nb_row-npt)*2+1]=tmpgoal.longitude
npt = npt - 1
}
return pathR
}
# create a table with only the path's points in order
function getPath(Q,nb){
path={.nb_col=2, .nb_row=0, .mat={}}
npt=0
# log("get the path from the point list")
while(nb!=1){
npt=npt+1
path.nb_row=npt
path.mat[(npt-1)*2]=rmat(Q,nb,1)
path.mat[(npt-1)*2+1]=rmat(Q,nb,2)
nb = rmat(Q,nb,3);
}
# log("re-order the list")
# table_print(path.mat)
pathR={.nb_col=2, .nb_row=path.nb_row, .mat={}}
while(npt>0){
tmpgoal = getvec(path,npt)
pathR.mat[(path.nb_row-npt)*2]=tmpgoal.x
pathR.mat[(path.nb_row-npt)*2+1]=tmpgoal.y
npt = npt - 1
}
#log("Double-check path: ", check_path(pathR, 1, cur_cell, 1))
return pathR
}

View File

@ -3,14 +3,22 @@
# FLIGHT-RELATED FUNCTIONS # FLIGHT-RELATED FUNCTIONS
# #
######################################## ########################################
TARGET_ALTITUDE = 5.0 include "rrtstar.bzz"
UAVSTATE = "TURNEDOFF"
function uav_initswarm(){ TARGET_ALTITUDE = 15.0 # m.
UAVSTATE = "TURNEDOFF"
PICTURE_WAIT = 20 # steps
GOTO_MAXVEL = 2 # m/steps
GOTO_MAXDIST = 150 # m.
GOTODIST_TOL = 0.5 # m.
GOTOANG_TOL = 0.1 # rad.
cur_goal_l = 0
rc_State = 0
homegps = {.lat=0, .long=0}
function uav_initswarm() {
s = swarm.create(1) s = swarm.create(1)
s.join() s.join()
statef=turnedoff
UAVSTATE = "TURNEDOFF"
} }
function turnedoff() { function turnedoff() {
@ -26,38 +34,130 @@ function idle() {
function takeoff() { function takeoff() {
UAVSTATE = "TAKEOFF" UAVSTATE = "TAKEOFF"
statef=takeoff statef=takeoff
#log("TakeOff: ", flight.status)
#log("Relative position: ", position.altitude)
if( flight.status == 2 and position.altitude >= TARGET_ALTITUDE-TARGET_ALTITUDE/20.0) { if( flight.status == 2 and position.altitude >= TARGET_ALTITUDE-TARGET_ALTITUDE/20.0) {
barrier_set(ROBOTS,action,land) barrier_set(ROBOTS, action, land, -1)
barrier_ready() barrier_ready()
#statef=hexagon } else {
} log("Altitude: ", position.altitude)
else {
log("Altitude: ", TARGET_ALTITUDE)
neighbors.broadcast("cmd", 22) neighbors.broadcast("cmd", 22)
uav_takeoff(TARGET_ALTITUDE) uav_takeoff(TARGET_ALTITUDE)
} }
} }
function land() { function land() {
UAVSTATE = "LAND" UAVSTATE = "LAND"
statef=land statef=land
#log("Land: ", flight.status)
if(flight.status == 2 or flight.status == 3){ neighbors.broadcast("cmd", 21)
neighbors.broadcast("cmd", 21) uav_land()
uav_land()
} if(flight.status != 2 and flight.status != 3) {
else { barrier_set(ROBOTS,turnedoff,land, 21)
barrier_set(ROBOTS,turnedoff,land)
barrier_ready() barrier_ready()
timeW=0
#barrier = nil
#statef=idle
} }
} }
function set_goto(transf) {
UAVSTATE = "GOTOGPS"
statef=function() {
gotoWP(transf)
}
if(rc_goto.id==id){
if(s!=nil){
if(s.in())
s.leave()
}
} else {
neighbors.broadcast("cmd", 16)
neighbors.broadcast("gt", rc_goto.id+rc_goto.longitude+rc_goto.latitude)
}
}
ptime=0
function picture() {
statef=picture
UAVSTATE="PICTURE"
uav_setgimbal(0.0, 0.0, -90.0, 20.0)
if(ptime==PICTURE_WAIT/2) { # wait for the drone to stabilize
uav_takepicture()
} else if(ptime>=PICTURE_WAIT) { # wait for the picture
statef=action
ptime=0
}
ptime=ptime+1
}
#
# still requires to be tuned, replaning takes too much time..
# DS 23/11/2017
function gotoWPRRT(transf) {
rc_goal = vec_from_gps(rc_goto.latitude, rc_goto.longitude)
homegps.lat = position.latitude
homegps.long = position.longitude
m_pos = math.vec2.scale(vec_from_gps(homegps.lat, homegps.long),-1)
print(" has to move ", math.vec2.length(rc_goal), "from ", m_pos.x, " ", m_pos.y)
if(math.vec2.length(rc_goal)>GOTO_MAXDIST*5)
log("Sorry this is too far.")
else {
if(Path==nil){
# create the map
if(map==nil)
UAVinit_map(rc_goal)
# add proximity sensor and neighbor obstacles to the map
while(Path==nil) {
#getproxobs(m_pos)
UAVgetneiobs (m_pos)
Path = UAVpathPlanner(rc_goal, m_pos)
}
cur_goal_l = 1
} else if(cur_goal_l<=Path.nb_row) {
cur_gps=getvec(Path,cur_goal_l) #x=latitude, y=longitude
cur_pt=vec_from_gps(cur_gps.x,cur_gps.y)
print(" heading to ", cur_pt.x,cur_pt.y)
if(math.vec2.length(cur_pt)>GOTODIST_TOL) {
m_pos = math.vec2.scale(vec_from_gps(homegps.lat, homegps.long),-1)
UAVgetneiobs(m_pos)
if(check_path(Path,cur_goal_l,m_pos,0)) {
uav_moveto(0.0, 0.0, rc_goto.altitude-position.altitude)
Path = nil
rc_goal = vec_from_gps(rc_goto.latitude, rc_goto.longitude)
while(Path == nil) {
#getproxobs(m_pos)
UAVgetneiobs (m_pos)
Path = UAVpathPlanner(rc_goal, m_pos)
}
cur_goal_l = 1
}
cur_pt = math.vec2.scale(cur_pt, GOTO_MAXVEL/math.vec2.length(cur_pt))
uav_moveto(cur_pt.x, cur_pt.y, rc_goto.altitude-position.altitude)
}
else
cur_goal_l = cur_goal_l + 1
} else {
Path = nil
transf()
}
}
}
function gotoWP(transf) {
m_navigation = vec_from_gps(rc_goto.latitude, rc_goto.longitude)
print(" has to move ", math.vec2.length(m_navigation), math.vec2.angle(m_navigation))
if(math.vec2.length(m_navigation)>GOTO_MAXDIST)
log("Sorry this is too far.")
else if(math.vec2.length(m_navigation)>GOTO_MAXVEL) { # limit velocity
m_navigation = math.vec2.scale(m_navigation, GOTO_MAXVEL/math.vec2.length(m_navigation))
uav_moveto(m_navigation.x, m_navigation.y, rc_goto.altitude-position.altitude)
} else if(math.vec2.length(m_navigation) < GOTODIST_TOL and math.vec2.angle(m_navigation) < GOTOANG_TOL) # reached destination
transf()
else
uav_moveto(m_navigation.x, m_navigation.y, rc_goto.altitude-position.altitude)
}
function follow() { function follow() {
if(size(targets)>0) { if(size(targets)>0) {
UAVSTATE = "FOLLOW" UAVSTATE = "FOLLOW"
@ -67,7 +167,7 @@ function follow() {
force=(0.05)*(tab.range)^4 force=(0.05)*(tab.range)^4
attractor=math.vec2.add(attractor, math.vec2.newp(force, tab.bearing)) attractor=math.vec2.add(attractor, math.vec2.newp(force, tab.bearing))
}) })
uav_moveto(attractor.x, attractor.y) uav_moveto(attractor.x, attractor.y, 0.0)
} else { } else {
log("No target in local table!") log("No target in local table!")
#statef=idle #statef=idle
@ -90,11 +190,8 @@ function uav_rccmd() {
neighbors.broadcast("cmd", 21) neighbors.broadcast("cmd", 21)
} else if(flight.rc_cmd==16) { } else if(flight.rc_cmd==16) {
flight.rc_cmd=0 flight.rc_cmd=0
UAVSTATE = "FOLLOW" UAVSTATE = "GOTOGPS"
log(rc_goto.latitude, " ", rc_goto.longitude) statef = goto
add_targetrb(0,rc_goto.latitude,rc_goto.longitude)
statef = follow
#uav_goto()
} else if(flight.rc_cmd==400) { } else if(flight.rc_cmd==400) {
flight.rc_cmd=0 flight.rc_cmd=0
uav_arm() uav_arm()
@ -106,21 +203,90 @@ function uav_rccmd() {
} else if (flight.rc_cmd==666){ } else if (flight.rc_cmd==666){
flight.rc_cmd=0 flight.rc_cmd=0
stattab_send() stattab_send()
} else if (flight.rc_cmd==900){
flight.rc_cmd=0
rc_State = 0
neighbors.broadcast("cmd", 900)
} else if (flight.rc_cmd==901){
flight.rc_cmd=0
rc_State = 1
neighbors.broadcast("cmd", 901)
} else if (flight.rc_cmd==902){
flight.rc_cmd=0
rc_State = 2
neighbors.broadcast("cmd", 902)
} else if (flight.rc_cmd==903){
flight.rc_cmd=0
rc_State = 3
neighbors.broadcast("cmd", 903)
} }
} }
function uav_neicmd() { function uav_neicmd() {
neighbors.listen("cmd", neighbors.listen("cmd",
function(vid, value, rid) { function(vid, value, rid) {
print("Got (", vid, ",", value, ") from robot #", rid) print("Got (", vid, ",", value, ") #", rid, "(", UAVSTATE, ")")
if(value==22 and UAVSTATE!="TAKEOFF") { if(value==22 and UAVSTATE!="TAKEOFF" and UAVSTATE!="BARRIERWAIT") {
statef=takeoff statef=takeoff
} else if(value==21) { UAVSTATE = "TAKEOFF"
statef=land } else if(value==21 and UAVSTATE!="LAND" and UAVSTATE!="BARRIERWAIT") {
} else if(value==400 and UAVSTATE=="IDLE") { statef=land
uav_arm() UAVSTATE = "LAND"
} else if(value==401 and UAVSTATE=="IDLE"){ } else if(value==400 and UAVSTATE=="TURNEDOFF") {
uav_disarm() uav_arm()
} } else if(value==401 and UAVSTATE=="TURNEDOFF"){
uav_disarm()
} else if(value==900){
rc_State = 0
} else if(value==901){
rc_State = 1
} else if(value==902){
rc_State = 2
} else if(value==903){
rc_State = 3
} else if(value==16 and UAVSTATE=="IDLE"){
# neighbors.listen("gt",function(vid, value, rid) {
# print("Got (", vid, ",", value, ") from robot #", rid)
# # if(gt.id == id) statef=goto
# })
}
}) })
} }
function LimitAngle(angle){
if(angle>2*math.pi)
return angle-2*math.pi
else if (angle<0)
return angle+2*math.pi
else
return angle
}
function vec_from_gps(lat, lon) {
d_lon = lon - position.longitude
d_lat = lat - position.latitude
ned_x = d_lat/180*math.pi * 6371000.0;
ned_y = d_lon/180*math.pi * 6371000.0 * math.cos(lat/180*math.pi);
#Lgoal.range = math.sqrt(ned_x*ned_x+ned_y*ned_y);
#Lgoal.bearing = LimitAngle(math.atan(ned_y,ned_x));
return math.vec2.new(ned_x,ned_y)
}
function gps_from_vec(vec) {
Lgoal = {.latitude=0, .longitude=0}
Vrange = math.vec2.length(vec)
Vbearing = LimitAngle(math.atan(vec.y, vec.x))
# print("rb2gps: ",Vrange,Vbearing,position.latitude,position.longitude)
latR = position.latitude*math.pi/180.0;
lonR = position.longitude*math.pi/180.0;
target_lat = math.asin(math.sin(latR) * math.cos(Vrange/6371000.0) + math.cos(latR) * math.sin(Vrange/6371000.0) * math.cos(Vbearing));
target_lon = lonR + math.atan(math.sin(Vbearing) * math.sin(Vrange/6371000.0) * math.cos(latR), math.cos(Vrange/6371000.0) - math.sin(latR) * math.sin(target_lat));
Lgoal.latitude = target_lat*180.0/math.pi;
Lgoal.longitude = target_lon*180.0/math.pi;
#d_lat = (vec.x / 6371000.0)*180.0/math.pi;
#goal.latitude = d_lat + position.latitude;
#d_lon = (vec.y / (6371000.0 * math.cos(goal.latitude*math.pi/180.0)))*180.0/math.pi;
#goal.longitude = d_lon + position.longitude;
return Lgoal
}

View File

@ -0,0 +1,152 @@
# Utilities
# Rads to degrees
function rtod(r) {
return (r*(180.0/math.pi))
}
# Copy a table
function table_deep_copy(new_t, old_t, depth) {
depth = depth - 1
if (old_t != nil) {
foreach(old_t, function(key, value) {
new_t[key] = value
if(depth != 0) {
new_t[key] = {}
table_deep_copy(new_t[key], value, depth)
}
})
}
}
function table_copy(old_t, depth) {
var t = {};
table_deep_copy(t, old_t, depth);
return t;
}
# Print the contents of a table
function table_print(t, depth) {
depth = depth - 1
if (t != nil) {
foreach(t, function(key, value) {
log(key, " -> ", value)
if(depth != 0) {
table_print(t[key], depth)
}
})
}
}
# Write a table as if it was a vector
function write_vector(k, index, val) {
var key = string.tostring(index)
k[key] = val
}
# Read a table as if it was a vector
function read_vector(k, index) {
var key = string.tostring(index)
if (k[key] == nil) {
return -1
} else {
return k[key]
}
}
# Write a table as if it was a matrix
function write_matrix(k, row, col, val) {
var key = string.concat(string.tostring(row),"-",string.tostring(col))
k[key] = val
}
# Read a table as if it was a matrix
function read_matrix(k, row, col) {
var key = string.concat(string.tostring(row),"-",string.tostring(col))
if (k[key] == nil) {
return -1
} else {
return k[key]
}
}
# Int to String
function itos(i) {
log("Use 'string.tostring(OJB)' instead")
if (i==0) { return "0" }
if (i==1) { return "1" }
if (i==2) { return "2" }
if (i==3) { return "3" }
if (i==4) { return "4" }
if (i==5) { return "5" }
if (i==6) { return "6" }
if (i==7) { return "7" }
if (i==8) { return "8" }
if (i==9) { return "9" }
log("Function 'itos' out of bounds, returning the answer (42)")
return "42"
}
# String to Int
function stoi(s) {
if (s=='0') { return 0 }
if (s=='1') { return 1 }
if (s=='2') { return 2 }
if (s=='3') { return 3 }
if (s=='4') { return 4 }
if (s=='5') { return 5 }
if (s=='6') { return 6 }
if (s=='7') { return 7 }
if (s=='8') { return 8 }
if (s=='9') { return 9 }
log("Function 'stoi' out of bounds, returning the answer (42)")
return 42
}
# Force angles in the (-pi,pi) interval
function radians_interval(a) {
var temp = a
while ((temp>2.0*math.pi) or (temp<0.0)) {
if (temp > 2.0*math.pi) {
temp = temp - 2.0*math.pi
} else if (temp < 0.0){
temp = temp + 2.0*math.pi
}
}
if (temp > math.pi) {
temp = temp - 2.0*math.pi
}
return temp
}
############################################
#base = {}
#base.create = function() {
# return {
# .method = function(a,b) {
# return a + b
# }
# }
# }
#x = base.create()
#x.method(3,4) # returns 7
#derived = {}
#derived.create = function() {
# b = base.create()
# b.method = function(a,b) {
# return a * b
# }
#}
#x = derived.create()
#x.method(3,4) # returns 12

View File

@ -41,7 +41,7 @@ math.vec2.length = function(v) {
# RETURN: The angle of the vector. # RETURN: The angle of the vector.
# #
math.vec2.angle = function(v) { math.vec2.angle = function(v) {
return math.atan2(v.y, v.x) return math.atan(v.y, v.x)
} }
# #

View File

@ -1,16 +1,29 @@
STATUS_VSTIG = 10 ########################################
GROUND_VSTIG = 11 #
# FLEET V.STIGMERGY-RELATED FUNCTIONS
#
########################################
#
# Constants
#
STATUS_VSTIG = 20
GROUND_VSTIG = 21
HIGHEST_ROBOTID = 14
WAIT4STEP = 10 WAIT4STEP = 10
v_status = {}
v_ground = {} #
# Init var
#
var v_status = {}
var v_ground = {}
b_updating = 0 b_updating = 0
counter=WAIT4STEP
function uav_initstig() { function uav_initstig() {
v_status = stigmergy.create(STATUS_VSTIG) v_status = stigmergy.create(STATUS_VSTIG)
v_ground = stigmergy.create(GROUND_VSTIG) v_ground = stigmergy.create(GROUND_VSTIG)
} }
counter=WAIT4STEP
function uav_updatestig() { function uav_updatestig() {
# TODO: Push values on update only. # TODO: Push values on update only.
if(counter<=0) { if(counter<=0) {
@ -78,7 +91,7 @@ function stattab_print() {
if(v_status.size()>0) { if(v_status.size()>0) {
if(b_updating==0) { if(b_updating==0) {
u=0 u=0
while(u<8){ while(u<HIGHEST_ROBOTID){
tab = v_status.get(u) tab = v_status.get(u)
if(tab!=nil) if(tab!=nil)
unpackstatus(tab) unpackstatus(tab)
@ -92,7 +105,7 @@ function stattab_send() {
if(v_status.size()>0) { if(v_status.size()>0) {
if(b_updating==0) { if(b_updating==0) {
u=0 u=0
while(u<8){ while(u<HIGHEST_ROBOTID){
tab = v_status.get(u) tab = v_status.get(u)
if(tab!=nil){ if(tab!=nil){
recv_value=tab recv_value=tab

View File

@ -0,0 +1,35 @@
include "vec2.bzz"
include "update.bzz"
include "barrier.bzz" # don't use a stigmergy id=80 (auto-increment up) with this header.
include "uavstates.bzz" # require an 'action' function to be defined here.
include "vstigenv.bzz"
function action() {
uav_storegoal(-1.0,-1.0,-1.0)
set_goto(picture)
}
# Executed once at init time.
function init() {
statef=turnedoff
UAVSTATE = "TURNEDOFF"
uav_initstig()
TARGET_ALTITUDE = 15.0
}
# Executed at each time step.
function step() {
uav_rccmd()
statef()
log("Current state: ", UAVSTATE)
}
# Executed once when the robot (or the simulator) is reset.
function reset() {
}
# Executed once at the end of experiment.
function destroy() {
}

View File

@ -3,21 +3,28 @@ include "update.bzz"
include "barrier.bzz" # don't use a stigmergy id=11 with this header. include "barrier.bzz" # don't use a stigmergy id=11 with this header.
include "uavstates.bzz" # require an 'action' function to be defined here. include "uavstates.bzz" # require an 'action' function to be defined here.
include "vstigenv.bzz" include "vstigenv.bzz"
include "rrtstar.bzz"
function action() { function action() {
statef=action statef=action
# test moveto cmd dx, dy uav_storegoal(45.5085,-73.1531935979886,5.0)
# uav_moveto(0.5, 0.5) set_goto(picture)
} }
# Executed once at init time. # Executed once at init time.
function init() { function init() {
statef=turnedoff
UAVSTATE = "TURNEDOFF"
uav_initstig()
} }
# Executed at each time step. # Executed at each time step.
function step() { function step() {
log("Altitude: ", position.altitude)
uav_rccmd() uav_rccmd()
statef()
log("Current state: ", UAVSTATE)
} }
# Executed once when the robot (or the simulator) is reset. # Executed once when the robot (or the simulator) is reset.

View File

@ -0,0 +1,35 @@
include "vec2.bzz"
include "update.bzz"
include "barrier.bzz" # don't use a stigmergy id=80 (auto-increment up) with this header.
include "uavstates.bzz" # require an 'action' function to be defined here.
include "vstigenv.bzz"
function action() {
uav_storegoal(-1.0,-1.0,-1.0)
set_goto(picture)
}
# Executed once at init time.
function init() {
statef=turnedoff
UAVSTATE = "TURNEDOFF"
uav_initstig()
TARGET_ALTITUDE = 15.0
}
# Executed at each time step.
function step() {
uav_rccmd()
statef()
log("Current state: ", UAVSTATE)
}
# Executed once when the robot (or the simulator) is reset.
function reset() {
}
# Executed once at the end of experiment.
function destroy() {
}

View File

@ -0,0 +1,537 @@
# Include files
include "string.bzz"
include "vec2.bzz"
include "utilities.bzz"
include "barrier.bzz"
############################################
# Global variables
RANGE = 200 # rab range in cm, get from argos file
N_SONS = 10 # Maximum number of sons
TRIGGER_VSTIG = 101 # ID of trigger virtual stigmergy
BARRIER_VSTIG = 102 # ID of barrier virtual stigmergy
################################################################
################################################################
# Tree utility functions
function parent_select() {
# Selects potential parents
var candidates = {}
candidates = neighbors.filter(function(rid, data) {
return ((knowledge.level[rid] > 0) and (data.distance < (RANGE - 10.0)) and (knowledge.free[rid] == 1))})
# and (data.distance > 10.0)
# Selects closest parent candidate as parent
var temp = {}
temp = candidates.reduce(function(rid, data, accum) {
accum.min = math.min(accum.min, data.distance)
return accum
}, {.min = RANGE})
var min = temp.min
var flag = 0
foreach(knowledge.distance, function(key, value) {
if ((flag == 0) and (candidates.data[key] != nil)) {
if (value == min) {
tree.parent.id = key
tree.parent.distance = value
tree.parent.azimuth = knowledge.azimuth[key]
flag = 1
}
}
#break (when implemented)
})
}
####################################
function count() {
if (nb_sons == 0) {
eq_level = level
}
else if (nb_sons >= 1) {
var temp = {}
temp = sons.reduce(function(rid, data, accum) {
accum.sum = accum.sum + tree.sons[rid].eq_level
return accum
}, {.sum = 0})
eq_level = temp.sum - (nb_sons - 1) * level
}
}
####################################
function change_frame(p01, p1, theta) {
var p0 = {
.x = math.cos(theta) * p1.x + math.sin(theta) * p1.y + p01.x,
.y = -math.sin(theta) * p1.x + math.cos(theta) * p1.y + p01.y
}
return p0
}
####################################
transform_accum = function(rid, data) {
# Son contribution in frame F1
var p1 = {
.x = tree.sons[rid].accum_x,
.y = tree.sons[rid].accum_y
}
# Rotation angle between F0 and F1
var theta = tree.sons[rid].angle_parent - data.azimuth - math.pi
# Translation vector from F0 to F1
var p01 = {
.x = 0,
.y = 0
}
var p0 = {}
if (tree.sons[rid].angle_parent != nil) {
var rot_angle = radians_interval(theta)
p0 = change_frame(p01, p1, rot_angle)
}
else {
p0.x = p1.x
p0.y = p1.y
}
return p0
}
####################################
function centroid() {
# If the robot has a parent
if ((tree.parent != nil) or (root == 1)) {
var sum_F1 = { .x = 0, .y = 0}
# If the robot has at least one son
if (nb_sons > 0) {
var temp = {}
# Expresses son contrib (in F1) in its own reference frame (F0)
temp = sons.map(transform_accum)
# Sums son contributions expressed in F0 frame
sum_F1 = temp.reduce(function(rid, data, accum) {
accum.x = accum.x + data.x
accum.y = accum.y + data.y
#log("id ", rid, " sum_x ", accum.x, " sum_y ", accum.y)
return accum
}, {.x = 0, .y = 0})
}
# If the robot is not the root
if ((root == 0) and (tree.parent.id != nil)) {
#var nb_descendants = eq_level - level
var p0 = knowledge.distance[tree.parent.id]#tree.parent.distance
var theta = knowledge.azimuth[tree.parent.id]#tree.parent.azimuth
# Adds current robot contribution to centroid sum
accum_x = sum_F1.x - (nb_descendants + 1) * p0 * math.cos(theta)
accum_y = sum_F1.y - (nb_descendants + 1) * p0 * math.sin(theta)
}
# If the robot is the root
else if ((root == 1) and (robot_count != 0)) {
# Centroid coordinates in root ref frame
accum_x = sum_F1.x / robot_count
accum_y = sum_F1.y / robot_count
}
}
}
################################################################
################################################################
# Tree reconfiguration functions
function tree_config() {
statef()
}
function end_fun() {
if (root == 1) {
log("centroid X: ", accum_x, " Y ", accum_y)
}
}
####################################
function root_select() {
log(id," root_select")
if (tree.parent.id != nil) {
if(neighbors.data[tree.parent.id] != nil) {
angle_parent = neighbors.data[tree.parent.id].azimuth
}
}
if (root == 1) {
# Listens for new root acknowledgment
foreach(knowledge.ackn, function(key, value) {
if (value == better_root) {
#log(id, " got it")
root = 0
level = 0
setleds(0,0,0)
}
})
if (ack == 1) {
# Triggers transition to new state
trigger.put("a", 1)
}
else if ((root == 1) and (better_root != id) and (trigger.get("a") != 1)) {
setleds(255,0,0)
better_root = id
# Centroid position in root reference frame (F0)
var c0 = math.vec2.new(accum_x, accum_y)
# Distance from current root to centroid
var dist_rc = math.vec2.length(c0)
#log("root ", id, " dist_centr ", dist_rc)
# Distances from neighbors to centroid
var dist_centroid = {}
dist_centroid = neighbors.map(function(rid, data) {
# Neighbour position in frame F0
var p0 = math.vec2.newp(data.distance, data.azimuth)
# Difference vector between p0 and c0
var v = math.vec2.sub(p0, c0)
# Distance between robot and centroid
return math.vec2.length(v)
})
# Minimal distance to centroid
var temp = {}
temp = dist_centroid.reduce(function(rid, data, accum) {
accum.min = math.min(accum.min, data)
return accum
}, {.min = dist_rc})
var min = temp.min
#log("min ", min)
# If the current root is the closest to the centroid
if(dist_rc == min) {
ack = 1
}
# Otherwise
else {
var flag = 0
# Selects closest robot to centroid as better root
foreach(dist_centroid.data, function(key, value) {
if(flag == 0) {
if(value == min) {
better_root = key
flag = 1
}
# break (when implemented)
}
})
#log(id, " better root : ", better_root)
#log("X : ", accum_x, "Y : ", accum_y)
var angle = neighbors.data[better_root].azimuth
# Broadcasts
var message = {
.better_root = better_root,
.centroid_x = accum_x,
.centroid_y = accum_y,
.angle_old_root = angle
}
neighbors.broadcast("msg1", message)
}
}
}
else if (better_root == nil) {
# Listen for old root message
foreach(knowledge.better_root, function(rid, value) {
if(value == id) {
var theta = neighbors.data[rid].azimuth
var p1 = {
.x = knowledge.centroid_x[rid],
.y = knowledge.centroid_y[rid]
}
var p01 = {
.x = neighbors.data[rid].distance * math.cos(theta),
.y = neighbors.data[rid].distance * math.sin(theta)
}
var p0 = {}
if (knowledge.angle_old_root[rid] != nil) {
var rot_angle = radians_interval(knowledge.angle_old_root[rid] - theta - math.pi)
p0 = change_frame(p01, p1, rot_angle)
}
else {
p0.x = p1.x
p0.y = p1.y
}
accum_x = p0.x
accum_y = p0.y
centroid_x = accum_x
centroid_y = accum_y
root = 1
neighbors.broadcast("got_it", id)
}
})
}
# Transitions to new state when all robots are ready
if (trigger.get("a") == 1) {
barrier_set(ROBOTS, end_fun)
barrier_ready()
}
}
####################################
function tree_select() {
log(id, " tree_select")
neighbors.map(function(rid, data) {
knowledge.distance[rid] = data.distance
knowledge.azimuth[rid] = data.azimuth
return 1
})
if (level == 0) {
# Finds a parent
parent_select()
# Updates robot level
if (tree.parent.id != nil) {
#log(" ")
#log("selected")
#log("son ", id)
#log("parent ", tree.parent.id)
#log(" ")
level = knowledge.level[tree.parent.id] + 1
angle_parent = neighbors.data[tree.parent.id].azimuth
}
}
else {
# Updates list of sons
foreach(knowledge.parent, function(key, value) {
if(value == id) {
#log(value)
if(tree.sons[key] == nil) {
# Updates robot nb_sons
nb_sons = nb_sons + 1
# Updates robot free status
if (nb_sons >= N_SONS) {
free = 0
}
}
tree.sons[key] = {
.distance = knowledge.distance[key],
.azimuth = knowledge.azimuth[key],
.eq_level = knowledge.eq_level[key],
.accum_x = knowledge.accum_x[key],
.accum_y = knowledge.accum_y[key],
.angle_parent = knowledge.angle_parent[key]
}
}
})
}
# Creates a subset of neighbors to get the sons
# and parent
sons = {}
sons = neighbors.filter(function(rid, data) {
return (tree.sons[rid] != nil)
})
parent = {}
parent = neighbors.filter(function(rid, data) {
return (tree.parent.id == rid)
})
# Counts robots (updates eq_level)
count()
# Updates count of robots in the tree
if (root == 1) {
robot_count = eq_level
}
nb_descendants = eq_level - level
# Computes centroid (updates accum_x, accum_y)
centroid()
# Broadcast information to other robots
var message = {
.level = level,
.parent = tree.parent.id,
.eq_level = eq_level,
.free = free,
.accum_x = accum_x,
.accum_y = accum_y,
.angle_parent = angle_parent
}
neighbors.broadcast("msg2", message)
# Triggers transition to new state if root count = ROBOTS
if (root == 1) {
if(robot_count == ROBOTS) {
log("centroid X: ", accum_x, " Y ", accum_y)
trigger.put("b", 1)
}
}
# Transitions to new state when all robots are ready
if (trigger.get("b") == 1) {
barrier_set(ROBOTS, root_select)
barrier_ready()
}
}
################################################################
################################################################
# This function is executed every time you press the 'execute' button
function init() {
trigger = stigmergy.create(TRIGGER_VSTIG)
barrier = stigmergy.create(BARRIER_VSTIG)
# Trees
old_tree = {}
tree = old_tree
old_tree.parent = {}
old_tree.sons = {}
# Boolean variables
root = 0 # Root status
free = 1 # Node status (true if accepts sons)
ack = 0
# Tree variables
level = 0
eq_level = 0
nb_sons = 0
nb_descendants = 0
# Update root status
if (id == 0) {
root = 1 # True if robot is the ro ot
level = 1
robot_count = 0
}
statef = tree_select
knowledge = {
.level = {},
.parent = {},
.eq_level = {},
.free = {},
.accum_x = {},
.accum_y = {},
.angle_parent = {},
.distance = {},
.azimuth = {},
.better_root = {},
.centroid_x = {},
.centroid_y = {},
.angle_old_root = {},
.ackn = {}
}
# Broadcast information to other robots
var message = {
.level = level,
.parent = old_tree.parent.id,
.eq_level = eq_level,
.free = free,
.accum_x = accum_x,
.accum_y = accum_y,
.angle_parent = 0.0
}
neighbors.broadcast("msg2", message)
# Listen to information from other robots for root_select
neighbors.listen("msg1", function(vid, value, rid) {
knowledge.better_root[rid] = value.better_root
knowledge.centroid_x[rid] = value.centroid_x
knowledge.centroid_y[rid] = value.centroid_y
knowledge.angle_old_root[rid] = value.angle_old_root
knowledge.angle_parent[rid] = value.angle_parent
})
# Listen to information from other robots for tree_select
neighbors.listen("msg2", function(vid, value, rid) {
knowledge.level[rid] = value.level
knowledge.parent[rid] = value.parent
knowledge.eq_level[rid] = value.eq_level
knowledge.free[rid] = value.free
knowledge.accum_x[rid] = value.accum_x
knowledge.accum_y[rid] = value.accum_y
knowledge.angle_parent[rid] = value.angle_parent
})
neighbors.listen("got_it", function(vid, value, rid) {
knowledge.ackn[rid] = value
})
}
############################################
# This function is executed at each time step
function step() {
tree_config()
goal = math.vec2.new(0.0, 0.0)
}
############################################
# This function is executed every time you press the 'reset'
# button in the GUI.
function reset() {
# put your code here
}
############################################
# This function is executed only once, when the robot is removed
# from the simulation
function destroy() {
# put your code here
}
################

View File

@ -23,8 +23,8 @@ struct pos_struct
typedef struct pos_struct Pos_struct; typedef struct pos_struct Pos_struct;
struct rb_struct struct rb_struct
{ {
double r,b,la,lo; double r,b,latitude,longitude,altitude;
rb_struct(double la, double lo, double r,double b):la(la),lo(lo),r(r),b(b){}; rb_struct(double la, double lo, double al, double r,double b):latitude(la),longitude(lo),altitude(al),r(r),b(b){};
rb_struct(){} rb_struct(){}
}; };
typedef struct rb_struct RB_struct; typedef struct rb_struct RB_struct;
@ -77,4 +77,6 @@ int get_robotid();
buzzvm_t get_vm(); buzzvm_t get_vm();
void set_robot_var(int ROBOTS); void set_robot_var(int ROBOTS);
int get_inmsg_size();
} }

View File

@ -9,8 +9,9 @@
#include "ros/ros.h" #include "ros/ros.h"
#include "buzz_utility.h" #include "buzz_utility.h"
#define EARTH_RADIUS (double) 6371000.0 #define EARTH_RADIUS (double) 6371000.0
#define DEG2RAD(DEG) ((DEG)*((M_PI)/(180.0))) #define DEG2RAD(DEG) (double) ((DEG)*((M_PI)/(180.0)))
#define RAD2DEG(RAD) (double) ((RAD)*((180.0)/(M_PI)))
namespace buzzuav_closures{ namespace buzzuav_closures{
typedef enum { typedef enum {
@ -22,6 +23,8 @@ namespace buzzuav_closures{
COMMAND_DISARM, COMMAND_DISARM,
COMMAND_GOTO, COMMAND_GOTO,
COMMAND_MOVETO, COMMAND_MOVETO,
COMMAND_PICTURE,
COMMAND_GIMBAL,
} Custom_CommandCode; } Custom_CommandCode;
/* /*
@ -30,19 +33,25 @@ namespace buzzuav_closures{
* The command to use in Buzz is buzzros_print takes any available datatype in Buzz * The command to use in Buzz is buzzros_print takes any available datatype in Buzz
*/ */
int buzzros_print(buzzvm_t vm); int buzzros_print(buzzvm_t vm);
void setWPlist(std::string path);
/* /*
* buzzuav_goto(latitude,longitude,altitude) function in Buzz * buzzuav_goto(latitude,longitude,altitude) function in Buzz
* commands the UAV to go to a position supplied * commands the UAV to go to a position supplied
*/ */
int buzz_floor(buzzvm_t vm);
int buzzuav_moveto(buzzvm_t vm); int buzzuav_moveto(buzzvm_t vm);
int buzzuav_goto(buzzvm_t vm); int buzzuav_storegoal(buzzvm_t vm);
int buzzuav_setgimbal(buzzvm_t vm);
void parse_gpslist();
int buzzuav_takepicture(buzzvm_t vm);
/* Returns the current command from local variable*/ /* Returns the current command from local variable*/
int getcmd(); int getcmd();
/*Sets goto position */ /*Sets goto position */
void set_goto(double pos[]); void set_goto(double pos[]);
/*Sets goto position from rc client*/ /*Sets goto position from rc client*/
void rc_set_goto(double pos[]); void rc_set_goto(int id, double latitude, double longitude, double altitude);
/*Sets gimbal orientation from rc client*/
void rc_set_gimbal(int id, float yaw, float roll, float pitch, float t);
/*sets rc requested command */ /*sets rc requested command */
void rc_call(int rc_cmd); void rc_call(int rc_cmd);
/* sets the battery state */ /* sets the battery state */
@ -56,6 +65,8 @@ void set_api_rssi(float value);
void set_currentpos(double latitude, double longitude, double altitude); void set_currentpos(double latitude, double longitude, double altitude);
/*retuns the current go to position */ /*retuns the current go to position */
double* getgoto(); double* getgoto();
std::string getuavstate();
float* getgimbal();
/* updates flight status*/ /* updates flight status*/
void flight_status_update(uint8_t state); void flight_status_update(uint8_t state);
/* Update neighbors table */ /* Update neighbors table */

View File

@ -39,6 +39,7 @@
#define XBEE_STOP_TRANSMISSION 4355356352 #define XBEE_STOP_TRANSMISSION 4355356352
#define TIMEOUT 60 #define TIMEOUT 60
#define BUZZRATE 10 #define BUZZRATE 10
#define CMD_REQUEST_UPDATE 666
using namespace std; using namespace std;
@ -54,6 +55,8 @@ public:
//void RosControllerInit(); //void RosControllerInit();
void RosControllerRun(); void RosControllerRun();
static const string CAPTURE_SRV_DEFAULT_NAME;
private: private:
struct num_robot_count struct num_robot_count
{ {
@ -68,8 +71,8 @@ private:
double longitude=0.0; double longitude=0.0;
double latitude=0.0; double latitude=0.0;
float altitude=0.0; float altitude=0.0;
}; typedef struct gps GPS ; // not useful in cpp }; typedef struct gps GPS ;
GPS target, home, cur_pos; GPS target, home, cur_pos;
double cur_rel_altitude; double cur_rel_altitude;
@ -91,7 +94,19 @@ private:
/*tmp to be corrected*/ /*tmp to be corrected*/
uint8_t no_cnt=0; uint8_t no_cnt=0;
uint8_t old_val=0 ; uint8_t old_val=0 ;
std::string bzzfile_name, fcclient_name, armclient, modeclient, rcservice_name,bcfname,dbgfname,out_payload,in_payload,obstacles_topic,stand_by,xbeesrv_name, setpoint_name; std::string bzzfile_name;
std::string fcclient_name;
std::string armclient;
std::string modeclient;
std::string rcservice_name;
std::string bcfname,dbgfname;
std::string out_payload;
std::string in_payload;
std::string obstacles_topic;
std::string stand_by;
std::string xbeesrv_name;
std::string capture_srv_name;
std::string setpoint_name;
std::string stream_client_name; std::string stream_client_name;
std::string relative_altitude_sub_name; std::string relative_altitude_sub_name;
std::string setpoint_nonraw; std::string setpoint_nonraw;
@ -101,6 +116,7 @@ private:
Num_robot_count count_robots; Num_robot_count count_robots;
ros::ServiceClient mav_client; ros::ServiceClient mav_client;
ros::ServiceClient xbeestatus_srv; ros::ServiceClient xbeestatus_srv;
ros::ServiceClient capture_srv;
ros::Publisher payload_pub; ros::Publisher payload_pub;
ros::Publisher MPpayload_pub; ros::Publisher MPpayload_pub;
ros::Publisher neigh_pos_pub; ros::Publisher neigh_pos_pub;
@ -110,6 +126,7 @@ private:
ros::Subscriber users_sub; ros::Subscriber users_sub;
ros::Subscriber battery_sub; ros::Subscriber battery_sub;
ros::Subscriber payload_sub; ros::Subscriber payload_sub;
ros::Subscriber flight_estatus_sub;
ros::Subscriber flight_status_sub; ros::Subscriber flight_status_sub;
ros::Subscriber obstacle_sub; ros::Subscriber obstacle_sub;
ros::Subscriber Robot_id_sub; ros::Subscriber Robot_id_sub;

View File

@ -1,59 +0,0 @@
<launch>
<group ns="gps">
<!-- NavSat Serial -->
<node pkg="nmea_comms" type="serial_node" name="nmea_serial_node" output="screen">
<param name="port" value="$(optenv HUSKY_NAVSAT_PORT /dev/clearpath/gps)" />
<param name="baud" value="$(optenv HUSKY_NAVSAT_BAUD 19200)" />
</node>
<!-- NavSat Processing -->
<node pkg="nmea_navsat_driver" type="nmea_topic_driver" name="nmea_topic_driver">
</node>
</group>
<node pkg="robot_localization" type="navsat_transform_node" name="navsat_transform" >
<rosparam>
magnetic_declination_radians: 0
roll_offset: 0
pitch_offset: 0
yaw_offset: 0
zero_altitude: false
broadcast_utm_transform: false
</rosparam>
</node>
<!-- run xbee>
<node pkg="xbee_ros_node" type="xbee_mav" name="xbee_mav" args="slave swarm" output="screen" />
<param name="Xbee_In_From_Buzz" type="str" value="outMavlink" />
<param name="Xbee_Out_To_Buzz" type="str" value="inMavlink" />
<param name="Xbee_In_From_Controller" type="str" value="xbee_cmd" / -->
<!-- xmee_mav Drone type and Commununication Mode -->
<!-- node pkg="xbee_ros_node" type="xbee_mav" name="xbee_mav" args="master solo" output="screen" -->
<node pkg="xbee_ros_node" type="xbee_mav" name="xbee_mav" args="slave swarm" output="screen" />
<!-- node pkg="xbee_ros_node" type="xbee_mav" name="xbee_mav" args="slave solo" output="screen" -->
<!--node pkg="xbee_ros_node" type="xbee_mav" name="xbee_mav" args="slave swarm" output="screen" -->
<!-- xmee_mav Topics and Services Names -->
<param name="Xbee_In_From_Buzz" type="str" value="outMavlink" />
<param name="Xbee_Out_To_Buzz" type="str" value="inMavlink" />
<param name="Xbee_In_From_Controller" type="str" value="xbee_cmd" />
<param name="Xbee_Out_To_Controller" type="str" value="mav_dji_cmd" />
<node pkg="dji_sdk_mistlab" type="dji_sdk_mav" name="dji_sdk_mav" output="screen"/>
<!-- run rosbuzz -->
<node name="rosbuzz_node" pkg="rosbuzz" type="rosbuzz_node" respawn="false" output="screen" >
<rosparam file="$(find rosbuzz)/launch/launch_config/husky.yaml"/>
<param name="bzzfile_name" value="$(find rosbuzz)/script/testflockfev.bzz" />
<param name="rcclient" value="true" />
<param name="rcservice_name" value="buzzcmd" />
<param name="in_payload" value="inMavlink"/>
<param name="out_payload" value="outMavlink"/>
<param name="xbee_status_srv" value="xbee_status"/>
<param name="xbee_plugged" value="true"/>
<param name="name" value="husky1"/>
<param name="stand_by" value="$(find rosbuzz)/script/stand_by.bzz"/>
</node>
</launch>

View File

@ -1,17 +0,0 @@
topics:
gps : global_position
localpos : local_position
battery : power_status
status : flight_status
fcclient : dji_mavcmd
setpoint : setpoint_position/local
armclient: dji_mavarm
modeclient: dji_mavmode
altitude: rel_alt
stream: set_stream_rate
type:
gps : sensor_msgs/NavSatFix
battery : mavros_msgs/BatteryStatus
status : mavros_msgs/ExtendedState
altitude: std_msgs/Float64

View File

@ -1,17 +0,0 @@
topics:
gps : global_position
localpos : local_position
battery : power_status
status : flight_status
fcclient : dji_mavcmd
setpoint : setpoint_position/local
armclient: dji_mavarm
modeclient: dji_mavmode
altitude: rel_alt
stream: set_stream_rate
type:
gps : sensor_msgs/NavSatFix
battery : mavros_msgs/BatteryStatus
status : mavros_msgs/ExtendedState
altitude: std_msgs/Float64

View File

@ -1,21 +0,0 @@
topics:
gps : mavros/global_position/global
battery : mavros/battery
status : mavros/state
fcclient: mavros/cmd/command
setpoint: mavros/setpoint_position/local
armclient: mavros/cmd/arming
modeclient: mavros/set_mode
localpos: /mavros/local_position/pose
stream: mavros/set_stream_rate
altitude: mavros/global_position/rel_alt
type:
gps : sensor_msgs/NavSatFix
# for SITL Solo
battery : mavros_msgs/BatteryState
# for solo
#battery : mavros_msgs/BatteryStatus
status : mavros_msgs/State
altitude: std_msgs/Float64
environment :
environment : solo-simulator

View File

@ -0,0 +1,12 @@
topics:
gps : global_position/global
battery : battery
status : state
estatus : extended_state
fcclient: cmd/command
setpoint: setpoint_position/local
armclient: cmd/arming
modeclient: set_mode
localpos: local_position/pose
stream: set_stream_rate
altitude: global_position/rel_alt

View File

@ -1,57 +0,0 @@
<launch>
<!-- RUN mavros -->
<arg name="fcu_url" default="/dev/ttyS0:115200" />
<arg name="gcs_url" default="" />
<arg name="tgt_system" default="1" />
<arg name="tgt_component" default="1" />
<arg name="log_output" default="screen" />
<include file="$(find mavros)/launch/node.launch">
<arg name="pluginlists_yaml" value="$(find mavros)/launch/apm_pluginlists.yaml" />
<arg name="config_yaml" value="$(find mavros)/launch/apm_config.yaml" />
<arg name="fcu_url" value="$(arg fcu_url)" />
<arg name="gcs_url" value="$(arg gcs_url)" />
<arg name="tgt_system" value="$(arg tgt_system)" />
<arg name="tgt_component" value="$(arg tgt_component)" />
<arg name="log_output" value="$(arg log_output)" />
</include>
<!-- set streaming rate -->
<!-- node pkg="rosservice" type="rosservice" name="freq" args="call /mavros/set_stream_rate 0 10 1" output="screen" / -->
<!-- run xbee>
<node pkg="xbee_ros_node" type="xbee_mav" name="xbee_mav" args="slave swarm" output="screen" />
<param name="Xbee_In_From_Buzz" type="str" value="outMavlink" />
<param name="Xbee_Out_To_Buzz" type="str" value="inMavlink" />
<param name="Xbee_In_From_Controller" type="str" value="xbee_cmd" / -->
<!-- xmee_mav Drone type and Commununication Mode -->
<!-- node pkg="xbee_ros_node" type="xbee_mav" name="xbee_mav" args="master solo" output="screen" -->
<node pkg="xbee_ros_node" type="xbee_mav" name="xbee_mav" args="slave swarm" output="screen" />
<!-- node pkg="xbee_ros_node" type="xbee_mav" name="xbee_mav" args="slave solo" output="screen" -->
<!--node pkg="xbee_ros_node" type="xbee_mav" name="xbee_mav" args="slave swarm" output="screen" -->
<!-- xmee_mav Topics and Services Names -->
<param name="Xbee_In_From_Buzz" type="str" value="outMavlink" />
<param name="Xbee_Out_To_Buzz" type="str" value="inMavlink" />
<param name="Xbee_In_From_Controller" type="str" value="xbee_cmd" />
<param name="Xbee_Out_To_Controller" type="str" value="mav_dji_cmd" />
<param name="USB_port" type="str" value="/dev/ttyUSB0" />
<param name="Baud_rate" type="double" value="230400" />
<!-- run rosbuzz -->
<node name="rosbuzz_node" pkg="rosbuzz" type="rosbuzz_node" respawn="false" output="screen" >
<rosparam file="$(find rosbuzz)/launch/launch_config/solo.yaml"/>
<param name="bzzfile_name" value="$(find rosbuzz)/buzz_scripts/flock.bzz" />
<param name="rcclient" value="true" />
<param name="rcservice_name" value="buzzcmd" />
<param name="in_payload" value="inMavlink"/>
<param name="out_payload" value="outMavlink"/>
<param name="xbee_status_srv" value="xbee_status"/>
<param name="xbee_plugged" value="true"/>
<param name="name" value="solos1"/>
<param name="stand_by" value="$(find rosbuzz)/buzz_scripts/stand_by.bzz"/>
</node>
</launch>

View File

@ -1,51 +0,0 @@
<launch>
<!-- RUN mavros
<arg name="fcu_url" default="tcp://127.0.0.1:5760" />
<arg name="gcs_url" default="" />
<arg name="tgt_system" default="1" />
<arg name="tgt_component" default="1" />
<arg name="log_output" default="screen" />
<include file="$(find mavros)/launch/node.launch">
<arg name="pluginlists_yaml" value="$(find mavros)/launch/apm_pluginlists.yaml" />
<arg name="config_yaml" value="$(find mavros)/launch/apm_config.yaml" />
<arg name="fcu_url" value="$(arg fcu_url)" />
<arg name="gcs_url" value="$(arg gcs_url)" />
<arg name="tgt_system" value="$(arg tgt_system)" />
<arg name="tgt_component" value="$(arg tgt_component)" />
<arg name="log_output" value="$(arg log_output)" />
</include>
-->
<!-- run xbee -->
<node pkg="xbee_ros_node" type="xbee_mav" name="xbee_mav" args="slave swarm" output="screen" />
<param name="Xbee_In_From_Buzz" type="str" value="outMavlink" />
<param name="Xbee_Out_To_Buzz" type="str" value="inMavlink" />
<param name="Xbee_In_From_Controller" type="str" value="xbee_cmd" />
<param name="Xbee_Out_To_Controller" type="str" value="mav_dji_cmd" />
<!-- run rosbuzz -->
<node name="rosbuzz_node" pkg="rosbuzz" type="rosbuzz_node" respawn="false" output="screen" >
<rosparam file="/home/ivan/catkin_ws/src/rosbuzz/launch/launch_config/solo.yaml"/>
<param name="bzzfile_name" value="/home/ivan/catkin_ws/src/rosbuzz/script/testsolo.bzz" />
<param name="rcclient" value="true" />
<param name="rcservice_name" value="buzzcmd" />
<param name="in_payload" value="inMavlink"/>
<param name="out_payload" value="outMavlink"/>
<param name="xbee_status_srv" value="xbee_status"/>
<param name="xbee_plugged" value="false"/>
<param name="name" value="solos1"/>
<param name="stand_by" value="/home/ivan/catkin_ws/src/rosbuzz/script/stand_by.bzz"/>
</node>
<!--
<node pkg="rosloader" type="rosloader" name="rosloader" output="screen"/>
-->
<!-- set streaming rate
/mavros/cmd/arming
<node pkg="rosservice" type="rosservice" name="stream_rate" args="call /mavros/set_stream_rate 0 10 1" />
-->
</launch>

View File

@ -1,43 +0,0 @@
<launch>
<!-- RUN mavros -->
<arg name="fcu_url" default="/dev/ttyAMA0:115200" />
<arg name="gcs_url" default="" />
<arg name="tgt_system" default="1" />
<arg name="tgt_component" default="1" />
<arg name="log_output" default="screen" />
<include file="$(find mavros)/launch/node.launch">
<arg name="pluginlists_yaml" value="$(find mavros)/launch/apm_pluginlists.yaml" />
<arg name="config_yaml" value="$(find mavros)/launch/apm_config.yaml" />
<arg name="fcu_url" value="$(arg fcu_url)" />
<arg name="gcs_url" value="$(arg gcs_url)" />
<arg name="tgt_system" value="$(arg tgt_system)" />
<arg name="tgt_component" value="$(arg tgt_component)" />
<arg name="log_output" value="$(arg log_output)" />
</include>
<!-- set streaming rate -->
<!-- node pkg="rosservice" type="rosservice" name="freq" args="call /mavros/set_stream_rate 0 10 1" output="screen" / -->
<!-- run xbee -->
<node pkg="xbee_ros_node" type="xbee_mav" name="xbee_mav" args="slave swarm" output="screen" />
<param name="Xbee_In_From_Buzz" type="str" value="outMavlink" />
<param name="Xbee_Out_To_Buzz" type="str" value="inMavlink" />
<param name="Xbee_In_From_Controller" type="str" value="xbee_cmd" />
<param name="No_of_dev" type="int" value="3" />
<!-- run rosbuzz -->
<node name="rosbuzz_node" pkg="rosbuzz" type="rosbuzz_node" respawn="false" output="screen" >
<rosparam file="/home/pi/ros_catkin_ws/src/ROSBuzz/launch/launch_config/solo.yaml"/>
<param name="bzzfile_name" value="/home/pi/ros_catkin_ws/src/ROSBuzz/src/testflockfev.bzz" />
<param name="rcclient" value="true" />
<param name="rcservice_name" value="/buzzcmd" />
<param name="in_payload" value="/inMavlink"/>
<param name="out_payload" value="/outMavlink"/>
<param name="robot_id" value="3"/>
<param name="No_of_Robots" value="3"/>
<param name="stand_by" value="/home/pi/ros_catkin_ws/src/ROSBuzz/src/stand_by.bo"/>
</node>
</launch>

View File

@ -1,14 +1,22 @@
<!-- Launch file for ROSBuzz --> <?xml version="1.0"?>
<!-- Generic launch file for ROSBuzz -->
<!-- This file is included in all ROS workspace launch files -->
<!-- Modify with great care! -->
<launch> <launch>
<node name="rosbuzz_node" pkg="rosbuzz" type="rosbuzz_node" respawn="false" output="screen" > <arg name="name" default="robot0"/>
<rosparam file="/home/ivan/catkin_ws/src/rosbuzz/launch/launch_config/solo.yaml"/> <arg name="xbee_plugged" default="true"/>
<param name="bzzfile_name" value="/home/ivan/catkin_ws/src/rosbuzz/src/testmoveto.bzz" /> <arg name="script" default="testalone"/>
<param name="rcclient" value="true" />
<param name="rcservice_name" value="/buzzcmd" /> <node name="rosbuzz_node" pkg="rosbuzz" type="rosbuzz_node" respawn="false" output="screen" >
<param name="in_payload" value="/inMavlink"/> <rosparam file="$(find rosbuzz)/launch/launch_config/topics.yaml"/>
<param name="out_payload" value="/outMavlink"/> <param name="bzzfile_name" value="$(find rosbuzz)/buzz_scripts/$(arg script).bzz" />
<param name="xbee_status_srv" value="/xbee_status"/> <param name="rcclient" value="true" />
<param name="stand_by" value="$(env ROS_WS)/src/ROSBuzz/src/stand_by.bo"/> <param name="rcservice_name" value="buzzcmd" />
</node> <param name="in_payload" value="inMavlink"/>
<param name="out_payload" value="outMavlink"/>
<param name="xbee_plugged" value="$(arg xbee_plugged)"/>
<param name="name" value="$(arg name)"/>
<param name="xbee_status_srv" value="xbee_status"/>
<param name="stand_by" value="$(find rosbuzz)/buzz_scripts/stand_by.bzz"/>
</node>
</launch> </launch>

View File

@ -1,27 +0,0 @@
<!-- Launch file for ROSBuzz -->
<launch>
<node name="rosbuzz_node" pkg="rosbuzz" type="rosbuzz_node" respawn="false" output="screen" >
<param name="bzzfile_name" value="/home/vivek/catkin_ws/src/rosbuzz/src/testflockfev_2parallel.bzz" />
<rosparam file="/home/vivek/catkin_ws/src/rosbuzz/launch/launch_config/m100.yaml"/>
<param name="rcclient" value="true" />
<param name="rcservice_name" value="rc_cmd" />
<param name="fcclient_name" value="/djicmd" />
<param name="in_payload" value="/inMavlink"/>
<!-- param name="in_payload" value="/rosbuzz_node1/outMavlink"-->
<param name="out_payload" value="/outMavlink"/>
<param name="robot_id" value="1"/>
<param name="No_of_Robots" value="1"/>
<param name="stand_by" value="/home/vivek/catkin_ws/src/rosbuzz/src/stand_by.bo"/>
</node>
<!-- node name="rosbuzz_node1" pkg="rosbuzz" type="rosbuzz_node" respawn="false" output="screen" -->
<!-- param name="bzzfile_name" value="/home/vivek/catkin_ws/src/rosbuzz/src/test1.bzz" -->
<!-- param name="rcclient" value="true" -->
<!-- param name="rcservice_name" value="rc_cmd" -->
<!-- param name="fcclient_name" value="/djicmd" -->
<!-- param name="in_payload" value="/rosbuzz_node/outMavlink"-->
<!-- param name="out_payload" value="outMavlink"-->
<!-- param name="robot_id" value="2"-->
<!-- node-->
</launch>

22
launch/rosbuzzd.launch Normal file
View File

@ -0,0 +1,22 @@
<?xml version="1.0"?>
<!-- Generic launch file for ROSBuzz -->
<!-- This file is included in all ROS workspace launch files -->
<!-- Modify with great care! -->
<launch>
<arg name="name" default="robot0"/>
<arg name="xbee_plugged" default="true"/>
<arg name="script" default="testalone"/>
<node name="rosbuzz_node" pkg="rosbuzz" type="rosbuzz_node" respawn="false" output="screen" launch-prefix="gdb -ex run --args">
<rosparam file="$(find rosbuzz)/launch/launch_config/topics.yaml"/>
<param name="bzzfile_name" value="$(find rosbuzz)/buzz_scripts/$(arg script).bzz" />
<param name="rcclient" value="true" />
<param name="rcservice_name" value="buzzcmd" />
<param name="in_payload" value="inMavlink"/>
<param name="out_payload" value="outMavlink"/>
<param name="xbee_plugged" value="$(arg xbee_plugged)"/>
<param name="name" value="$(arg name)"/>
<param name="xbee_status_srv" value="xbee_status"/>
<param name="stand_by" value="$(find rosbuzz)/buzz_scripts/stand_by.bzz"/>
</node>
</launch>

View File

@ -1,16 +0,0 @@
<!-- Launch file for ROSBuzz -->
<launch>
<node name="rosbuzz_node" pkg="rosbuzz" type="rosbuzz_node" respawn="false" output="screen">
<rosparam file="$(find rosbuzz)/launch/launch_config/m100.yaml"/>
<param name="bzzfile_name" value="$(find rosbuzz)/script/testflockfev.bzz" />
<param name="rcclient" value="true" />
<param name="rcservice_name" value="buzzcmd" />
<param name="in_payload" value="inMavlink"/>
<param name="out_payload" value="outMavlink"/>
<param name="xbee_plugged" value="true"/>
<param name="name" value="m1001"/>
<param name="xbee_status_srv" value="xbee_status"/>
<param name="stand_by" value="$(find rosbuzz)/script/stand_by.bzz"/>
</node>
</launch>

View File

@ -31,5 +31,10 @@ function stoprobot {
} }
function updaterobot { function updaterobot {
# rosrun robot_upstart install --logdir ~/ROS_WS/log/ robot_upstart/launch/m100buzzynocam.launch # rosrun robot_upstart install --logdir ~/ROS_WS/log/ robot_upstart/launch/m100buzzynocam.launch
rosrun robot_upstart install --logdir ~/ROS_WS/log/ dji_sdk_mistlab/launch/m100buzzy.launch rosrun robot_upstart install --logdir /media/key/ROS_WS/log/ dji_sdk_mistlab/launch_robot/m100buzzy.launch
# rosrun robot_upstart install --logdir ~/ROS_WS/log/ dji_sdk_mistlab/launch_robot/m100TXbuzzy.launch
}
function uavstate {
let "a = $1 + 900"
rosservice call robot0/buzzcmd 0 $a 0 0 0 0 0 0 0 0
} }

View File

@ -17,7 +17,6 @@ namespace buzz_utility{
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 MSG_SIZE = 500; // Only 250 bytes of Buzz messages every step (limited to Xbee frame size)
static uint32_t MAX_MSG_SIZE = 10000; // Maximum Msg size for sending update packets static uint32_t MAX_MSG_SIZE = 10000; // 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;
@ -229,7 +228,7 @@ void in_message_process(){
buzzmsg_payload_t m = buzzoutmsg_queue_first(VM); buzzmsg_payload_t m = buzzoutmsg_queue_first(VM);
/* Make sure the next message makes the data buffer with buzz messages to be less than MAX SIZE Bytes */ /* Make sure the next message makes the data buffer with buzz messages to be less than MAX SIZE Bytes */
//ROS_INFO("read size : %i", (int)(tot + buzzmsg_payload_size(m) + sizeof(uint16_t))); //ROS_INFO("read size : %i", (int)(tot + buzzmsg_payload_size(m) + sizeof(uint16_t)));
if((uint32_t)(tot + buzzmsg_payload_size(m) + sizeof(uint16_t)) > MSG_SIZE) { if((uint32_t)(tot + buzzmsg_payload_size(m) + sizeof(uint16_t)) > MAX_MSG_SIZE) {
buzzmsg_payload_destroy(&m); buzzmsg_payload_destroy(&m);
break; break;
} }
@ -304,8 +303,14 @@ void in_message_process(){
buzzvm_pushs(VM, buzzvm_string_register(VM, "uav_moveto", 1)); buzzvm_pushs(VM, buzzvm_string_register(VM, "uav_moveto", 1));
buzzvm_pushcc(VM, buzzvm_function_register(VM, buzzuav_closures::buzzuav_moveto)); buzzvm_pushcc(VM, buzzvm_function_register(VM, buzzuav_closures::buzzuav_moveto));
buzzvm_gstore(VM); buzzvm_gstore(VM);
buzzvm_pushs(VM, buzzvm_string_register(VM, "uav_goto", 1)); buzzvm_pushs(VM, buzzvm_string_register(VM, "uav_storegoal", 1));
buzzvm_pushcc(VM, buzzvm_function_register(VM, buzzuav_closures::buzzuav_goto)); buzzvm_pushcc(VM, buzzvm_function_register(VM, buzzuav_closures::buzzuav_storegoal));
buzzvm_gstore(VM);
buzzvm_pushs(VM, buzzvm_string_register(VM, "uav_setgimbal", 1));
buzzvm_pushcc(VM, buzzvm_function_register(VM, buzzuav_closures::buzzuav_setgimbal));
buzzvm_gstore(VM);
buzzvm_pushs(VM, buzzvm_string_register(VM, "uav_takepicture", 1));
buzzvm_pushcc(VM, buzzvm_function_register(VM, buzzuav_closures::buzzuav_takepicture));
buzzvm_gstore(VM); buzzvm_gstore(VM);
buzzvm_pushs(VM, buzzvm_string_register(VM, "uav_arm", 1)); buzzvm_pushs(VM, buzzvm_string_register(VM, "uav_arm", 1));
buzzvm_pushcc(VM, buzzvm_function_register(VM, buzzuav_closures::buzzuav_arm)); buzzvm_pushcc(VM, buzzvm_function_register(VM, buzzuav_closures::buzzuav_arm));
@ -349,7 +354,13 @@ void in_message_process(){
buzzvm_pushs(VM, buzzvm_string_register(VM, "uav_moveto", 1)); buzzvm_pushs(VM, buzzvm_string_register(VM, "uav_moveto", 1));
buzzvm_pushcc(VM, buzzvm_function_register(VM, buzzuav_closures::dummy_closure)); buzzvm_pushcc(VM, buzzvm_function_register(VM, buzzuav_closures::dummy_closure));
buzzvm_gstore(VM); buzzvm_gstore(VM);
buzzvm_pushs(VM, buzzvm_string_register(VM, "uav_goto", 1)); buzzvm_pushs(VM, buzzvm_string_register(VM, "uav_storegoal", 1));
buzzvm_pushcc(VM, buzzvm_function_register(VM, buzzuav_closures::dummy_closure));
buzzvm_gstore(VM);
buzzvm_pushs(VM, buzzvm_string_register(VM, "uav_setgimbal", 1));
buzzvm_pushcc(VM, buzzvm_function_register(VM, buzzuav_closures::dummy_closure));
buzzvm_gstore(VM);
buzzvm_pushs(VM, buzzvm_string_register(VM, "uav_takepicture", 1));
buzzvm_pushcc(VM, buzzvm_function_register(VM, buzzuav_closures::dummy_closure)); buzzvm_pushcc(VM, buzzvm_function_register(VM, buzzuav_closures::dummy_closure));
buzzvm_gstore(VM); buzzvm_gstore(VM);
buzzvm_pushs(VM, buzzvm_string_register(VM, "uav_arm", 1)); buzzvm_pushs(VM, buzzvm_string_register(VM, "uav_arm", 1));
@ -487,7 +498,7 @@ int create_stig_tables() {
if(buzzvm_set_bcode(VM, BO_BUF, bcode_size) != BUZZVM_STATE_READY) { if(buzzvm_set_bcode(VM, BO_BUF, bcode_size) != BUZZVM_STATE_READY) {
buzzvm_destroy(&VM); buzzvm_destroy(&VM);
buzzdebug_destroy(&DBG_INFO); buzzdebug_destroy(&DBG_INFO);
ROS_ERROR("%s: Error loading Buzz script", bo_filename); ROS_ERROR("[%i] %s: Error loading Buzz script", Robot_id, bo_filename);
return 0; return 0;
} }
/* Register hook functions */ /* Register hook functions */
@ -498,6 +509,11 @@ int create_stig_tables() {
return 0; return 0;
} }
// Initialize UAVSTATE variable
buzzvm_pushs(VM, buzzvm_string_register(VM, "UAVSTATE", 1));
buzzvm_pushs(VM, buzzvm_string_register(VM, "TURNEDOFF", 1));
buzzvm_gstore(VM);
/* Create vstig tables /* Create vstig tables
if(create_stig_tables() != BUZZVM_STATE_READY) { if(create_stig_tables() != BUZZVM_STATE_READY) {
buzzvm_destroy(&VM); buzzvm_destroy(&VM);
@ -550,16 +566,22 @@ int create_stig_tables() {
if(buzzvm_set_bcode(VM, UP_BO_BUF, bcode_size) != BUZZVM_STATE_READY) { if(buzzvm_set_bcode(VM, UP_BO_BUF, bcode_size) != BUZZVM_STATE_READY) {
buzzvm_destroy(&VM); buzzvm_destroy(&VM);
buzzdebug_destroy(&DBG_INFO); buzzdebug_destroy(&DBG_INFO);
fprintf(stdout, "%s: Error loading Buzz script\n\n", BO_FNAME); ROS_ERROR("[%i] %s: Error loading Buzz bytecode (update)", Robot_id);
return 0; return 0;
} }
// Register hook functions // Register hook functions
if(buzz_register_hooks() != BUZZVM_STATE_READY) { if(buzz_register_hooks() != BUZZVM_STATE_READY) {
buzzvm_destroy(&VM); buzzvm_destroy(&VM);
buzzdebug_destroy(&DBG_INFO); buzzdebug_destroy(&DBG_INFO);
fprintf(stdout, "%s: Error registering hooks\n\n", BO_FNAME); ROS_ERROR("[%i] Error registering hooks (update)", Robot_id);
return 0; return 0;
} }
// Initialize UAVSTATE variable
buzzvm_pushs(VM, buzzvm_string_register(VM, "UAVSTATE", 1));
buzzvm_pushs(VM, buzzvm_string_register(VM, "TURNEDOFF", 1));
buzzvm_gstore(VM);
/* Create vstig tables /* Create vstig tables
if(create_stig_tables() != BUZZVM_STATE_READY) { if(create_stig_tables() != BUZZVM_STATE_READY) {
buzzvm_destroy(&VM); buzzvm_destroy(&VM);
@ -606,16 +628,22 @@ int create_stig_tables() {
if(buzzvm_set_bcode(VM, UP_BO_BUF, bcode_size) != BUZZVM_STATE_READY) { if(buzzvm_set_bcode(VM, UP_BO_BUF, bcode_size) != BUZZVM_STATE_READY) {
buzzvm_destroy(&VM); buzzvm_destroy(&VM);
buzzdebug_destroy(&DBG_INFO); buzzdebug_destroy(&DBG_INFO);
fprintf(stdout, "%s: Error loading Buzz script\n\n", BO_FNAME); ROS_ERROR("[%i] %s: Error loading Buzz bytecode (update init)", Robot_id);
return 0; return 0;
} }
// Register hook functions // Register hook functions
if(testing_buzz_register_hooks() != BUZZVM_STATE_READY) { if(testing_buzz_register_hooks() != BUZZVM_STATE_READY) {
buzzvm_destroy(&VM); buzzvm_destroy(&VM);
buzzdebug_destroy(&DBG_INFO); buzzdebug_destroy(&DBG_INFO);
fprintf(stdout, "%s: Error registering hooks\n\n", BO_FNAME); ROS_ERROR("[%i] Error registering hooks (update init)", Robot_id);
return 0; return 0;
} }
// Initialize UAVSTATE variable
buzzvm_pushs(VM, buzzvm_string_register(VM, "UAVSTATE", 1));
buzzvm_pushs(VM, buzzvm_string_register(VM, "TURNEDOFF", 1));
buzzvm_gstore(VM);
/* Create vstig tables /* Create vstig tables
if(create_stig_tables() != BUZZVM_STATE_READY) { if(create_stig_tables() != BUZZVM_STATE_READY) {
buzzvm_destroy(&VM); buzzvm_destroy(&VM);
@ -786,4 +814,8 @@ int create_stig_tables() {
buzzvm_pushi(VM, ROBOTS); buzzvm_pushi(VM, ROBOTS);
buzzvm_gstore(VM); buzzvm_gstore(VM);
} }
int get_inmsg_size(){
return IN_MSG.size();
}
} }

View File

@ -16,82 +16,93 @@ namespace buzzuav_closures{
//void set_ros_controller_ptr(const rosbzz_node::roscontroller* roscontroller_ptrin); //void set_ros_controller_ptr(const rosbzz_node::roscontroller* roscontroller_ptrin);
static double goto_pos[3]; static double goto_pos[3];
static double rc_goto_pos[3]; static double rc_goto_pos[3];
static float rc_gimbal[4];
static float batt[3]; static float batt[3];
static float obst[5]={0,0,0,0,0}; static float obst[5]={0,0,0,0,0};
static double cur_pos[3]; static double cur_pos[3];
static uint8_t status; static uint8_t status;
static int cur_cmd = 0; static int cur_cmd = 0;
static int rc_cmd=0; static int rc_cmd=0;
static int rc_id=-1;
static int buzz_cmd=0; static int buzz_cmd=0;
static float height=0; static float height=0;
static bool deque_full = false; static bool deque_full = false;
static int rssi = 0; static int rssi = 0;
static int message_number = 0; static float raw_packet_loss = 0.0;
static float raw_packet_loss = 0.0; static int filtered_packet_loss = 0;
static int filtered_packet_loss = 0; static float api_rssi = 0.0;
static float api_rssi = 0.0; string WPlistname = "";
std::map< int, buzz_utility::RB_struct> targets_map; std::map< int, buzz_utility::RB_struct> targets_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;
/****************************************/ /****************************************/
/****************************************/ /****************************************/
int buzzros_print(buzzvm_t vm) { int buzzros_print(buzzvm_t vm)
int i; {
char buffer [50] = ""; std::ostringstream buffer (std::ostringstream::ate);
sprintf(buffer,"%s [%i]", buffer, (int)buzz_utility::get_robotid()); buffer << buzz_utility::get_robotid();
for(i = 1; i < buzzdarray_size(vm->lsyms->syms); ++i) { for (uint32_t index = 1; index < buzzdarray_size(vm->lsyms->syms); ++index)
buzzvm_lload(vm, i); {
buzzobj_t o = buzzvm_stack_at(vm, 1); buzzvm_lload(vm, index);
buzzvm_pop(vm); buzzobj_t o = buzzvm_stack_at(vm, 1);
switch(o->o.type) { buzzvm_pop(vm);
case BUZZTYPE_NIL: switch (o->o.type)
sprintf(buffer,"%s BUZZ - [nil]", buffer); {
break; case BUZZTYPE_NIL:
case BUZZTYPE_INT: buffer << " BUZZ - [nil]";
sprintf(buffer,"%s %d", buffer, o->i.value); break;
//fprintf(stdout, "%d", o->i.value); case BUZZTYPE_INT:
break; buffer << " " << o->i.value;
case BUZZTYPE_FLOAT: break;
sprintf(buffer,"%s %f", buffer, o->f.value); case BUZZTYPE_FLOAT:
break; buffer << " " << o->f.value;
case BUZZTYPE_TABLE: break;
sprintf(buffer,"%s [table with %d elems]", buffer, (buzzdict_size(o->t.value))); case BUZZTYPE_TABLE:
break; buffer << " [table with " << buzzdict_size(o->t.value) << " elems]";
case BUZZTYPE_CLOSURE: break;
if(o->c.value.isnative) case BUZZTYPE_CLOSURE:
sprintf(buffer,"%s [n-closure @%d]", buffer, o->c.value.ref); if (o->c.value.isnative)
else {
sprintf(buffer,"%s [c-closure @%d]", buffer, o->c.value.ref); buffer << " [n-closure @" << o->c.value.ref << "]";
break; }
case BUZZTYPE_STRING: else
sprintf(buffer,"%s %s", buffer, o->s.value.str); {
break; buffer << " [c-closure @" << o->c.value.ref << "]";
case BUZZTYPE_USERDATA: }
sprintf(buffer,"%s [userdata @%p]", buffer, o->u.value); break;
break; case BUZZTYPE_STRING:
default: buffer << " " << o->s.value.str;
break; break;
} case BUZZTYPE_USERDATA:
} buffer << " [userdata @" << o->u.value << "]";
ROS_INFO(buffer); break;
//fprintf(stdout, "\n"); default:
return buzzvm_ret0(vm); break;
} }
}
ROS_INFO("%s",buffer.str().c_str());
return buzzvm_ret0(vm);
}
void setWPlist(string path){
WPlistname = path + "include/graphs/waypointlist.csv";
}
/*----------------------------------------/ /*----------------------------------------/
/ Compute GPS destination from current position and desired Range and Bearing / Compute GPS destination from current position and desired Range and Bearing
/----------------------------------------*/ /----------------------------------------*/
void gps_from_rb(double range, double bearing, double out[3]) { void gps_from_rb(double range, double bearing, double out[3]) {
double lat = cur_pos[0]*M_PI/180.0; double lat = RAD2DEG(cur_pos[0]);
double lon = cur_pos[1]*M_PI/180.0; double lon = RAD2DEG(cur_pos[1]);
out[0] = asin(sin(lat) * cos(range/EARTH_RADIUS) + cos(lat) * sin(range/EARTH_RADIUS) * cos(bearing)); out[0] = asin(sin(lat) * cos(range/EARTH_RADIUS) + cos(lat) * sin(range/EARTH_RADIUS) * cos(bearing));
out[1] = lon + atan2(sin(bearing) * sin(range/EARTH_RADIUS) * cos(lat), cos(range/EARTH_RADIUS) - sin(lat)*sin(out[0])); out[1] = lon + atan2(sin(bearing) * sin(range/EARTH_RADIUS) * cos(lat), cos(range/EARTH_RADIUS) - sin(lat)*sin(out[0]));
out[0] = out[0]*180.0/M_PI; out[0] = RAD2DEG(out[0]);
out[1] = out[1]*180.0/M_PI; out[1] = RAD2DEG(out[1]);
out[2] = height; //constant height. out[2] = height; //constant height.
} }
@ -103,10 +114,10 @@ namespace buzzuav_closures{
} }
void rb_from_gps(double nei[], double out[], double cur[]){ void rb_from_gps(double nei[], double out[], double cur[]){
double d_lon = nei[1] - cur[1]; double d_lon = nei[1] - cur[1];
double d_lat = nei[0] - cur[0]; double d_lat = nei[0] - cur[0];
double ned_x = DEG2RAD(d_lat) * EARTH_RADIUS; double ned_x = DEG2RAD(d_lat) * EARTH_RADIUS;
double ned_y = DEG2RAD(d_lon) * EARTH_RADIUS * cos(DEG2RAD(nei[0])); double ned_y = DEG2RAD(d_lon) * EARTH_RADIUS * cos(DEG2RAD(nei[0]));
out[0] = sqrt(ned_x*ned_x+ned_y*ned_y); out[0] = sqrt(ned_x*ned_x+ned_y*ned_y);
out[1] = constrainAngle(atan2(ned_y,ned_x)); out[1] = constrainAngle(atan2(ned_y,ned_x));
out[2] = 0.0; out[2] = 0.0;
@ -117,31 +128,78 @@ namespace buzzuav_closures{
double hcpos2[4] = {45.564729, -73.562060, 45.564362, -73.562958}; double hcpos2[4] = {45.564729, -73.562060, 45.564362, -73.562958};
double hcpos3[4] = {45.564969, -73.562838, 45.564636, -73.563677}; double hcpos3[4] = {45.564969, -73.562838, 45.564636, -73.563677};
void parse_gpslist()
{
// Open file:
ROS_INFO("WP list file: %s", WPlistname.c_str());
std::ifstream fin(WPlistname.c_str()); // Open in text-mode.
// Opening may fail, always check.
if (!fin) {
ROS_ERROR("GPS list parser, could not open file.");
return;
}
// Prepare a C-string buffer to be used when reading lines.
const int MAX_LINE_LENGTH = 1024; // Choose this large enough for your need.
char buffer[MAX_LINE_LENGTH] = {};
const char * DELIMS = "\t ,"; // Tab, space or comma.
// Read the file and load the data:
double lat, lon;
int alt, tilt, tid;
buzz_utility::RB_struct RB_arr;
// Read one line at a time.
while ( fin.getline(buffer, MAX_LINE_LENGTH) ) {
// Extract the tokens:
tid = atoi(strtok( buffer, DELIMS ));
lon = atof(strtok( NULL, DELIMS ));
lat = atof(strtok( NULL, DELIMS ));
alt = atoi(strtok( NULL, DELIMS ));
tilt = atoi(strtok( NULL, DELIMS ));
//ROS_INFO("%.6f, %.6f, %i %i %i",lat, lon, alt, tilt, tid);
RB_arr.latitude=lat;
RB_arr.longitude=lon;
RB_arr.altitude=alt;
// Insert elements.
map< int, buzz_utility::RB_struct >::iterator it = wplist_map.find(tid);
if(it!=wplist_map.end())
wplist_map.erase(it);
wplist_map.insert(make_pair(tid, RB_arr));
}
ROS_INFO("----->Saved %i waypoints.", wplist_map.size());
// Close the file:
fin.close();
}
/*----------------------------------------/ /*----------------------------------------/
/ Buzz closure to move following a 2D vector / Buzz closure to move following a 2D vector
/----------------------------------------*/ /----------------------------------------*/
int buzzuav_moveto(buzzvm_t vm) { int buzzuav_moveto(buzzvm_t vm) {
buzzvm_lnum_assert(vm, 2); buzzvm_lnum_assert(vm, 3);
buzzvm_lload(vm, 1); /* dx */ buzzvm_lload(vm, 1); /* dx */
buzzvm_lload(vm, 2); /* dy */ buzzvm_lload(vm, 2); /* dy */
//buzzvm_lload(vm, 3); /* Latitude */ buzzvm_lload(vm, 3); /* dheight */
//buzzvm_type_assert(vm, 3, BUZZTYPE_FLOAT); buzzvm_type_assert(vm, 3, BUZZTYPE_FLOAT);
buzzvm_type_assert(vm, 2, BUZZTYPE_FLOAT); buzzvm_type_assert(vm, 2, BUZZTYPE_FLOAT);
buzzvm_type_assert(vm, 1, BUZZTYPE_FLOAT); buzzvm_type_assert(vm, 1, BUZZTYPE_FLOAT);
float dy = buzzvm_stack_at(vm, 1)->f.value; float dh = buzzvm_stack_at(vm, 1)->f.value;
float dx = buzzvm_stack_at(vm, 2)->f.value; float dy = buzzvm_stack_at(vm, 2)->f.value;
double d = sqrt(dx*dx+dy*dy); //range float dx = buzzvm_stack_at(vm, 3)->f.value;
goto_pos[0]=dx; goto_pos[0]=dx;
goto_pos[1]=dy; goto_pos[1]=dy;
goto_pos[2]=height; goto_pos[2]=height+dh;
/*double b = atan2(dy,dx); //bearing /*double b = atan2(dy,dx); //bearing
printf(" Vector for Goto: %.7f,%.7f\n",dx,dy); printf(" Vector for Goto: %.7f,%.7f\n",dx,dy);
gps_from_rb(d, b, goto_pos); gps_from_rb(d, b, goto_pos);
cur_cmd=mavros_msgs::CommandCode::NAV_WAYPOINT;*/ cur_cmd=mavros_msgs::CommandCode::NAV_WAYPOINT;*/
//printf(" Vector for Goto: %.7f,%.7f\n",dx,dy); //printf(" Vector for Goto: %.7f,%.7f\n",dx,dy);
//ROS_WARN("[%i] Buzz requested Move To: x: %.7f , y: %.7f, z: %.7f", (int)buzz_utility::get_robotid(), goto_pos[0], goto_pos[1], goto_pos[2]); //ROS_WARN("[%i] Buzz requested Move To: x: %.7f , y: %.7f, z: %.7f", (int)buzz_utility::get_robotid(), goto_pos[0], goto_pos[1], goto_pos[2]);
buzz_cmd= COMMAND_MOVETO; // TO DO what should we use buzz_cmd = COMMAND_MOVETO; // TO DO what should we use
return buzzvm_ret0(vm); return buzzvm_ret0(vm);
} }
int buzzuav_update_targets(buzzvm_t vm) { int buzzuav_update_targets(buzzvm_t vm) {
@ -156,27 +214,27 @@ namespace buzzuav_closures{
double rb[3], tmp[3]; double rb[3], tmp[3];
map< int, buzz_utility::RB_struct >::iterator it; map< int, buzz_utility::RB_struct >::iterator it;
for (it=targets_map.begin(); it!=targets_map.end(); ++it){ for (it=targets_map.begin(); it!=targets_map.end(); ++it){
tmp[0]=(it->second).la;tmp[1]=(it->second).lo;tmp[2]=height; tmp[0]=(it->second).latitude; tmp[1]=(it->second).longitude; tmp[2]=height;
rb_from_gps(tmp, rb, cur_pos); rb_from_gps(tmp, rb, cur_pos);
ROS_WARN("----------Pushing target id %i (%f,%f)", rb[0], rb[1]); //ROS_WARN("----------Pushing target id %i (%f,%f)", it->first, rb[0], rb[1]);
buzzvm_push(vm, targettbl); buzzvm_push(vm, targettbl);
/* When we get here, the "targets" table is on top of the stack */ // When we get here, the "targets" table is on top of the stack
//ROS_INFO("Buzz_utility will save user %i.", it->first); //ROS_INFO("Buzz_utility will save user %i.", it->first);
/* Push user id */ // Push user id
buzzvm_pushi(vm, it->first); buzzvm_pushi(vm, it->first);
/* Create entry table */ // Create entry table
buzzobj_t entry = buzzheap_newobj(vm->heap, BUZZTYPE_TABLE); buzzobj_t entry = buzzheap_newobj(vm->heap, BUZZTYPE_TABLE);
/* Insert range */ // Insert range
buzzvm_push(vm, entry); buzzvm_push(vm, entry);
buzzvm_pushs(vm, buzzvm_string_register(vm, "range", 1)); buzzvm_pushs(vm, buzzvm_string_register(vm, "range", 1));
buzzvm_pushf(vm, rb[0]); buzzvm_pushf(vm, rb[0]);
buzzvm_tput(vm); buzzvm_tput(vm);
/* Insert longitude */ // Insert longitude
buzzvm_push(vm, entry); buzzvm_push(vm, entry);
buzzvm_pushs(vm, buzzvm_string_register(vm, "bearing", 1)); buzzvm_pushs(vm, buzzvm_string_register(vm, "bearing", 1));
buzzvm_pushf(vm, rb[1]); buzzvm_pushf(vm, rb[1]);
buzzvm_tput(vm); buzzvm_tput(vm);
/* Save entry into data table */ // Save entry into data table
buzzvm_push(vm, entry); buzzvm_push(vm, entry);
buzzvm_tput(vm); buzzvm_tput(vm);
} }
@ -204,8 +262,9 @@ namespace buzzuav_closures{
if(fabs(rb[0])<100.0) { if(fabs(rb[0])<100.0) {
//printf("\tGot new user from bzz stig: %i - %f, %f\n", uid, rb[0], rb[1]); //printf("\tGot new user from bzz stig: %i - %f, %f\n", uid, rb[0], rb[1]);
buzz_utility::RB_struct RB_arr; buzz_utility::RB_struct RB_arr;
RB_arr.la=tmp[0]; RB_arr.latitude=tmp[0];
RB_arr.lo=tmp[1]; RB_arr.longitude=tmp[1];
RB_arr.altitude=tmp[2];
RB_arr.r=rb[0]; RB_arr.r=rb[0];
RB_arr.b=rb[1]; RB_arr.b=rb[1];
map< int, buzz_utility::RB_struct >::iterator it = targets_map.find(uid); map< int, buzz_utility::RB_struct >::iterator it = targets_map.find(uid);
@ -215,30 +274,30 @@ namespace buzzuav_closures{
//ROS_INFO("Buzz_utility got updated/new user: %i (%f,%f,%f)", id, latitude, longitude, altitude); //ROS_INFO("Buzz_utility got updated/new user: %i (%f,%f,%f)", id, latitude, longitude, altitude);
return vm->state; return vm->state;
} else } else
printf(" ---------- Target too far %f\n",rb[0]); ROS_WARN(" ---------- Target too far %f",rb[0]);
return 0; return 0;
} }
int buzzuav_addNeiStatus(buzzvm_t vm){ int buzzuav_addNeiStatus(buzzvm_t vm){
buzzvm_lnum_assert(vm, 5); buzzvm_lnum_assert(vm, 5);
buzzvm_lload(vm, 1); // fc buzzvm_lload(vm, 1); // fc
buzzvm_lload(vm, 2); // xbee buzzvm_lload(vm, 2); // xbee
buzzvm_lload(vm, 3); // batt buzzvm_lload(vm, 3); // batt
buzzvm_lload(vm, 4); // gps buzzvm_lload(vm, 4); // gps
buzzvm_lload(vm, 5); // id buzzvm_lload(vm, 5); // id
buzzvm_type_assert(vm, 5, BUZZTYPE_INT); buzzvm_type_assert(vm, 5, BUZZTYPE_INT);
buzzvm_type_assert(vm, 4, BUZZTYPE_INT); buzzvm_type_assert(vm, 4, BUZZTYPE_INT);
buzzvm_type_assert(vm, 3, BUZZTYPE_INT); buzzvm_type_assert(vm, 3, BUZZTYPE_INT);
buzzvm_type_assert(vm, 2, BUZZTYPE_INT); buzzvm_type_assert(vm, 2, BUZZTYPE_INT);
buzzvm_type_assert(vm, 1, BUZZTYPE_INT); buzzvm_type_assert(vm, 1, BUZZTYPE_INT);
buzz_utility::neighbors_status newRS; buzz_utility::neighbors_status newRS;
uint8_t id = buzzvm_stack_at(vm, 5)->i.value; uint8_t id = buzzvm_stack_at(vm, 5)->i.value;
newRS.gps_strenght= buzzvm_stack_at(vm, 4)->i.value; newRS.gps_strenght= buzzvm_stack_at(vm, 4)->i.value;
newRS.batt_lvl= buzzvm_stack_at(vm, 3)->i.value; newRS.batt_lvl= buzzvm_stack_at(vm, 3)->i.value;
newRS.xbee= buzzvm_stack_at(vm, 2)->i.value; newRS.xbee= buzzvm_stack_at(vm, 2)->i.value;
newRS.flight_status= buzzvm_stack_at(vm, 1)->i.value; newRS.flight_status= buzzvm_stack_at(vm, 1)->i.value;
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);
neighbors_status_map.insert(make_pair(id, newRS)); neighbors_status_map.insert(make_pair(id, newRS));
@ -247,7 +306,7 @@ namespace buzzuav_closures{
mavros_msgs::Mavlink get_status(){ mavros_msgs::Mavlink get_status(){
mavros_msgs::Mavlink payload_out; mavros_msgs::Mavlink payload_out;
map< int, buzz_utility::neighbors_status >::iterator it; map< int, buzz_utility::neighbors_status >::iterator it;
for (it= neighbors_status_map.begin(); it!= neighbors_status_map.end(); ++it){ for (it= neighbors_status_map.begin(); it!= neighbors_status_map.end(); ++it){
payload_out.payload64.push_back(it->first); payload_out.payload64.push_back(it->first);
payload_out.payload64.push_back(it->second.gps_strenght); payload_out.payload64.push_back(it->second.gps_strenght);
@ -263,15 +322,69 @@ namespace buzzuav_closures{
return payload_out; return payload_out;
} }
/*----------------------------------------/ /*----------------------------------------/
/ Buzz closure to go directly to a GPS destination from the Mission Planner / Buzz closure to take a picture here.
/----------------------------------------*/ /----------------------------------------*/
int buzzuav_goto(buzzvm_t vm) { int buzzuav_takepicture(buzzvm_t vm) {
rc_goto_pos[2]=height; //cur_cmd = mavros_msgs::CommandCode::CMD_DO_SET_CAM_TRIGG_DIST;
set_goto(rc_goto_pos); buzz_cmd = COMMAND_PICTURE;
cur_cmd=mavros_msgs::CommandCode::NAV_WAYPOINT; return buzzvm_ret0(vm);
printf(" Buzz requested Go To, to Latitude: %.7f , Longitude: %.7f, Altitude: %.7f \n",goto_pos[0],goto_pos[1],goto_pos[2]); }
buzz_cmd=COMMAND_GOTO;
return buzzvm_ret0(vm); /*----------------------------------------/
/ Buzz closure to change locally the gimbal orientation
/----------------------------------------*/
int buzzuav_setgimbal(buzzvm_t vm) {
buzzvm_lnum_assert(vm, 4);
buzzvm_lload(vm, 1); // time
buzzvm_lload(vm, 2); // pitch
buzzvm_lload(vm, 3); // roll
buzzvm_lload(vm, 4); // yaw
buzzvm_type_assert(vm, 4, BUZZTYPE_FLOAT);
buzzvm_type_assert(vm, 3, BUZZTYPE_FLOAT);
buzzvm_type_assert(vm, 2, BUZZTYPE_FLOAT);
buzzvm_type_assert(vm, 1, BUZZTYPE_FLOAT);
rc_gimbal[0] = buzzvm_stack_at(vm, 4)->f.value;
rc_gimbal[1] = buzzvm_stack_at(vm, 3)->f.value;
rc_gimbal[2] = buzzvm_stack_at(vm, 2)->f.value;
rc_gimbal[3] = buzzvm_stack_at(vm, 1)->f.value;
ROS_WARN("Set RC_GIMBAL ---- %f %f %f (%f)",rc_gimbal[0],rc_gimbal[1],rc_gimbal[2],rc_gimbal[3]);
buzz_cmd = COMMAND_GIMBAL;
return buzzvm_ret0(vm);
}
/*----------------------------------------/
/ Buzz closure to store locally a GPS destination from the fleet
/----------------------------------------*/
int buzzuav_storegoal(buzzvm_t vm) {
buzzvm_lnum_assert(vm, 3);
buzzvm_lload(vm, 1); // altitude
buzzvm_lload(vm, 2); // longitude
buzzvm_lload(vm, 3); // latitude
buzzvm_type_assert(vm, 3, BUZZTYPE_FLOAT);
buzzvm_type_assert(vm, 2, BUZZTYPE_FLOAT);
buzzvm_type_assert(vm, 1, BUZZTYPE_FLOAT);
double goal[3];
goal[0] = buzzvm_stack_at(vm, 3)->f.value;
goal[1] = buzzvm_stack_at(vm, 2)->f.value;
goal[2] = buzzvm_stack_at(vm, 1)->f.value;
if(goal[0]==-1 && goal[1]==-1 && goal[2]==-1){
if(wplist_map.size()<=0)
parse_gpslist();
goal[0] = wplist_map.begin()->second.latitude;
goal[1] = wplist_map.begin()->second.longitude;
goal[2] = wplist_map.begin()->second.altitude;
wplist_map.erase(wplist_map.begin()->first);
}
double rb[3];
rb_from_gps(goal, rb, cur_pos);
if(fabs(rb[0])<150.0)
rc_set_goto((int)buzz_utility::get_robotid(), goal[0], goal[1], goal[2]);
ROS_WARN("Set RC_GOTO ---- %f %f %f (%f %f, %f %f)",goal[0],goal[1],goal[2],cur_pos[0],cur_pos[1],rb[0],rb[1]);
return buzzvm_ret0(vm);
} }
/*----------------------------------------/ /*----------------------------------------/
@ -327,6 +440,20 @@ namespace buzzuav_closures{
return goto_pos; return goto_pos;
} }
float* getgimbal() {
return rc_gimbal;
}
string getuavstate() {
static buzzvm_t VM = buzz_utility::get_vm();
std::stringstream state_buff;
buzzvm_pushs(VM, buzzvm_string_register(VM, "UAVSTATE",1));
buzzvm_gload(VM);
buzzobj_t uav_state = buzzvm_stack_at(VM, 1);
buzzvm_pop(VM);
return uav_state->s.value.str;
}
int getcmd() { int getcmd() {
return cur_cmd; return cur_cmd;
} }
@ -344,12 +471,24 @@ namespace buzzuav_closures{
return cmd; return cmd;
} }
void rc_set_goto(double pos[]) { void rc_set_goto(int id, double latitude, double longitude, double altitude) {
rc_goto_pos[0] = pos[0]; rc_id = id;
rc_goto_pos[1] = pos[1]; rc_goto_pos[0] = latitude;
rc_goto_pos[2] = pos[2]; rc_goto_pos[1] = longitude;
rc_goto_pos[2] = altitude;
} }
void rc_set_gimbal(int id, float yaw, float roll, float pitch, float t) {
rc_id = id;
rc_gimbal[0] = yaw;
rc_gimbal[1] = roll;
rc_gimbal[2] = pitch;
rc_gimbal[3] = t;
}
void rc_call(int rc_cmd_in) { void rc_call(int rc_cmd_in) {
rc_cmd = rc_cmd_in; rc_cmd = rc_cmd_in;
} }
@ -517,6 +656,10 @@ namespace buzzuav_closures{
buzzvm_pushs(vm, buzzvm_string_register(vm, "rc_goto", 1)); buzzvm_pushs(vm, buzzvm_string_register(vm, "rc_goto", 1));
buzzvm_pusht(vm); buzzvm_pusht(vm);
buzzvm_dup(vm); buzzvm_dup(vm);
buzzvm_pushs(vm, buzzvm_string_register(vm, "id", 1));
buzzvm_pushi(vm, rc_id);
buzzvm_tput(vm);
buzzvm_dup(vm);
buzzvm_pushs(vm, buzzvm_string_register(vm, "latitude", 1)); buzzvm_pushs(vm, buzzvm_string_register(vm, "latitude", 1));
buzzvm_pushf(vm, rc_goto_pos[0]); buzzvm_pushf(vm, rc_goto_pos[0]);
buzzvm_tput(vm); buzzvm_tput(vm);

View File

@ -2,6 +2,9 @@
#include <thread> #include <thread>
namespace rosbzz_node { namespace rosbzz_node {
const string roscontroller::CAPTURE_SRV_DEFAULT_NAME = "/image_sender/capture_image";
const bool debug = false;
/*--------------- /*---------------
/Constructor /Constructor
---------------*/ ---------------*/
@ -17,6 +20,7 @@ roscontroller::roscontroller(ros::NodeHandle &n_c, ros::NodeHandle &n_c_priv)
bcfname = fname + ".bo"; bcfname = fname + ".bo";
dbgfname = fname + ".bdb"; dbgfname = fname + ".bdb";
set_bzz_file(bzzfile_name.c_str()); set_bzz_file(bzzfile_name.c_str());
buzzuav_closures::setWPlist(bzzfile_name.substr(0, bzzfile_name.find_last_of("\\/")) + "/");
/*Initialize variables*/ /*Initialize variables*/
// Solo things // Solo things
SetMode("LOITER", 0); SetMode("LOITER", 0);
@ -46,7 +50,14 @@ roscontroller::roscontroller(ros::NodeHandle &n_c, ros::NodeHandle &n_c_priv)
} }
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 += "Update.log"; path = path.substr(0, bzzfile_name.find_last_of("\\/"))+"/log/";
std::string folder_check="mkdir -p "+path;
system(folder_check.c_str());
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());
}
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);
} }
@ -185,9 +196,13 @@ void roscontroller::RosControllerRun()
/* Set the Buzz bytecode */ /* Set the Buzz bytecode */
if (buzz_utility::buzz_script_set(bcfname.c_str(), dbgfname.c_str(), if (buzz_utility::buzz_script_set(bcfname.c_str(), dbgfname.c_str(),
robot_id)) { robot_id)) {
int packet_loss_tmp,time_step=0;
double cur_packet_loss=0;
ROS_INFO("[%i] Bytecode file found and set", robot_id); ROS_INFO("[%i] Bytecode file found and set", robot_id);
std::string standby_bo = Compile_bzz(stand_by) + ".bo"; std::string standby_bo = Compile_bzz(stand_by) + ".bo";
init_update_monitor(bcfname.c_str(), standby_bo.c_str()); //init_update_monitor(bcfname.c_str(), standby_bo.c_str());
/*loop rate of ros*/
ros::Rate loop_rate(BUZZRATE);
/////////////////////////////////////////////////////// ///////////////////////////////////////////////////////
// MAIN LOOP // MAIN LOOP
////////////////////////////////////////////////////// //////////////////////////////////////////////////////
@ -195,11 +210,43 @@ void roscontroller::RosControllerRun()
while (ros::ok() && !buzz_utility::buzz_script_done()) { while (ros::ok() && !buzz_utility::buzz_script_done()) {
/*Update neighbors position inside Buzz*/ /*Update neighbors position inside Buzz*/
// buzz_closure::neighbour_pos_callback(neighbours_pos_map); // buzz_closure::neighbour_pos_callback(neighbours_pos_map);
/*log ROS Time stamp, pos (lat,long,alt), Swarm size, no. of neigh,
neigh pos, RSSI val, Packet loss, filtered packet loss*/
log<<ros::Time::now()<<",";
log<<cur_pos.latitude << "," << cur_pos.longitude << ","
<< cur_pos.altitude << ",";
log << (int)no_of_robots<<",";
map<int, buzz_utility::Pos_struct>::iterator it =
neighbours_pos_map.begin();
log << neighbours_pos_map.size()<< ",";
for (; it != neighbours_pos_map.end(); ++it)
{
log << (double)it->second.x << "," << (double)it->second.y
<< "," << (double)it->second.z << ",";
}
const uint8_t shrt_id= 0xFF;
float result;
/*Neighbours of the robot published with id in respective topic*/ /*Neighbours of the robot published with id in respective topic*/
neighbours_pos_publisher(); neighbours_pos_publisher();
send_MPpayload(); send_MPpayload();
/*Check updater state and step code*/ /*Check updater state and step code*/
update_routine(bcfname.c_str(), dbgfname.c_str()); // update_routine(bcfname.c_str(), dbgfname.c_str());
if(time_step==BUZZRATE){
time_step=0;
cur_packet_loss= 1 -( (double)packet_loss_tmp/(BUZZRATE*( (int)no_of_robots-1 )) );
packet_loss_tmp=0;
if(cur_packet_loss<0) cur_packet_loss=0;
else if (cur_packet_loss>1) cur_packet_loss=1;
}
else{
packet_loss_tmp+=(int)buzz_utility::get_inmsg_size();
time_step++;
}
if(debug) ROS_WARN("CURRENT PACKET DROP : %f ",cur_packet_loss);
/*Log In Msg queue size*/
log<<(int)buzz_utility::get_inmsg_size()<<",";
/*Step buzz script */ /*Step buzz script */
buzz_utility::buzz_script_step(); buzz_utility::buzz_script_step();
/*Prepare messages and publish them in respective topic*/ /*Prepare messages and publish them in respective topic*/
@ -207,13 +254,13 @@ void roscontroller::RosControllerRun()
/*call flight controler service to set command long*/ /*call flight controler service to set command long*/
flight_controller_service_call(); flight_controller_service_call();
/*Set multi message available after update*/ /*Set multi message available after update*/
if (get_update_status()) //if (get_update_status())
{ //{
set_read_update_status(); /* set_read_update_status();
multi_msg = true; multi_msg = true;
log << cur_pos.latitude << "," << cur_pos.longitude << "," log << cur_pos.latitude << "," << cur_pos.longitude << ","
<< cur_pos.altitude << ","; << cur_pos.altitude << ",";
collect_data(log); collect_data(log);
map<int, buzz_utility::Pos_struct>::iterator it = map<int, buzz_utility::Pos_struct>::iterator it =
neighbours_pos_map.begin(); neighbours_pos_map.begin();
log << "," << neighbours_pos_map.size(); log << "," << neighbours_pos_map.size();
@ -222,26 +269,29 @@ void roscontroller::RosControllerRun()
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;
} }
log << std::endl; log << std::endl;*/
} //}
/*Set ROBOTS variable for barrier in .bzz from neighbours count*/ /*Set ROBOTS variable for barrier in .bzz from neighbours count*/
// no_of_robots=get_number_of_robots(); // no_of_robots=get_number_of_robots();
get_number_of_robots(); get_number_of_robots();
buzz_utility::set_robot_var(no_of_robots); buzz_utility::set_robot_var(no_of_robots);
/*Retrive the state of the graph and uav and log*/
std::stringstream state_buff;
state_buff << buzzuav_closures::getuavstate();
log<<state_buff.str()<<std::endl;
// if(neighbours_pos_map.size() >0) no_of_robots // if(neighbours_pos_map.size() >0) no_of_robots
// =neighbours_pos_map.size()+1; // =neighbours_pos_map.size()+1;
// buzz_utility::set_robot_var(no_of_robots); // buzz_utility::set_robot_var(no_of_robots);
/*Set no of robots for updates TODO only when not updating*/ /*Set no of robots for updates TODO only when not updating*/
// if(multi_msg) // if(multi_msg)
updates_set_robots(no_of_robots); //updates_set_robots(no_of_robots);
// ROS_INFO("ROBOTS: %i , acutal : //get_xbee_status(); // commented out because it may slow down the node too much, to be tested
// %i",(int)no_of_robots,(int)buzzdict_size(buzz_utility::get_vm()->swarmmembers)+1);
get_xbee_status();
/*run once*/ /*run once*/
ros::spinOnce(); ros::spinOnce();
/*loop rate of ros*/
ros::Rate loop_rate(BUZZRATE);
loop_rate.sleep(); loop_rate.sleep();
// make sure to sleep for the remainder of our cycle time
if (loop_rate.cycleTime() > ros::Duration(1.0 / (float)BUZZRATE))
ROS_WARN("ROSBuzz loop missed its desired rate of %iHz... the loop actually took %.4f seconds", BUZZRATE, loop_rate.cycleTime().toSec());
if (fcu_timeout <= 0) if (fcu_timeout <= 0)
buzzuav_closures::rc_call(mavros_msgs::CommandCode::NAV_LAND); buzzuav_closures::rc_call(mavros_msgs::CommandCode::NAV_LAND);
else else
@ -266,7 +316,8 @@ void roscontroller::Rosparameters_get(ros::NodeHandle &n_c)
/*Obtain .bzz file name from parameter server*/ /*Obtain .bzz file name from parameter server*/
if (n_c.getParam("bzzfile_name", bzzfile_name)) if (n_c.getParam("bzzfile_name", bzzfile_name))
; ;
else { else
{
ROS_ERROR("Provide a .bzz file to run in Launch file"); ROS_ERROR("Provide a .bzz file to run in Launch file");
system("rosnode kill rosbuzz_node"); system("rosnode kill rosbuzz_node");
} }
@ -284,13 +335,11 @@ void roscontroller::Rosparameters_get(ros::NodeHandle &n_c)
{ {
ROS_INFO("RC service is disabled"); ROS_INFO("RC service is disabled");
} }
} else { } else
{
ROS_ERROR("Provide a rc client option: yes or no in Launch file"); ROS_ERROR("Provide a rc client option: yes or no in Launch file");
system("rosnode kill rosbuzz_node"); system("rosnode kill rosbuzz_node");
} }
/*Obtain robot_id from parameter server*/
// n_c.getParam("robot_id", robot_id);
// robot_id=(int)buzz_utility::get_robotid();
/*Obtain out payload name*/ /*Obtain out payload name*/
n_c.getParam("out_payload", out_payload); n_c.getParam("out_payload", out_payload);
/*Obtain in payload name*/ /*Obtain in payload name*/
@ -300,21 +349,26 @@ void roscontroller::Rosparameters_get(ros::NodeHandle &n_c)
if (n_c.getParam("xbee_plugged", xbeeplugged)) if (n_c.getParam("xbee_plugged", xbeeplugged))
; ;
else { else
{
ROS_ERROR("Provide the xbee plugged boolean in Launch file"); ROS_ERROR("Provide the xbee plugged boolean in Launch file");
system("rosnode kill rosbuzz_node"); system("rosnode kill rosbuzz_node");
} }
if (!xbeeplugged) { if (!xbeeplugged) {
if (n_c.getParam("name", robot_name)) if (n_c.getParam("name", robot_name))
; ;
else { else
{
ROS_ERROR("Provide the xbee plugged boolean in Launch file"); ROS_ERROR("Provide the xbee plugged boolean in Launch file");
system("rosnode kill rosbuzz_node"); system("rosnode kill rosbuzz_node");
} }
} else } else
n_c.getParam("xbee_status_srv", xbeesrv_name); n_c.getParam("xbee_status_srv", xbeesrv_name);
std::cout << "////////////////// " << xbeesrv_name; if(!n_c.getParam("capture_image_srv", capture_srv_name))
{
capture_srv_name = CAPTURE_SRV_DEFAULT_NAME;
}
GetSubscriptionParameters(n_c); GetSubscriptionParameters(n_c);
// initialize topics to null? // initialize topics to null?
@ -325,70 +379,71 @@ used
/-----------------------------------------------------------------------------------*/ /-----------------------------------------------------------------------------------*/
void roscontroller::GetSubscriptionParameters(ros::NodeHandle &node_handle) void roscontroller::GetSubscriptionParameters(ros::NodeHandle &node_handle)
{ {
// todo: make it as an array in yaml?
m_sMySubscriptions.clear(); m_sMySubscriptions.clear();
std::string gps_topic, gps_type; std::string gps_topic, gps_type;
if (node_handle.getParam("topics/gps", gps_topic)) if (node_handle.getParam("topics/gps", gps_topic))
; ;
else { else
{
ROS_ERROR("Provide a gps topic in Launch file"); ROS_ERROR("Provide a gps topic in Launch file");
system("rosnode kill rosbuzz_node"); system("rosnode kill rosbuzz_node");
} }
node_handle.getParam("type/gps", gps_type); m_smTopic_infos.insert(pair<std::string, std::string>(gps_topic, "sensor_msgs/NavSatFix"));
m_smTopic_infos.insert(pair<std::string, std::string>(gps_topic, gps_type));
std::string battery_topic, battery_type; std::string battery_topic;
node_handle.getParam("topics/battery", battery_topic); node_handle.getParam("topics/battery", battery_topic);
node_handle.getParam("type/battery", battery_type); m_smTopic_infos.insert(pair<std::string, std::string>(battery_topic, "mavros_msgs/BatteryStatus"));
m_smTopic_infos.insert(
pair<std::string, std::string>(battery_topic, battery_type));
std::string status_topic, status_type; std::string status_topic;
node_handle.getParam("topics/status", status_topic); node_handle.getParam("topics/status", status_topic);
node_handle.getParam("type/status", status_type); m_smTopic_infos.insert(pair<std::string, std::string>(status_topic, "mavros_msgs/State"));
m_smTopic_infos.insert( node_handle.getParam("topics/estatus", status_topic);
pair<std::string, std::string>(status_topic, status_type)); m_smTopic_infos.insert(pair<std::string, std::string>(status_topic, "mavros_msgs/ExtendedState"));
std::string altitude_topic, altitude_type; std::string altitude_topic;
node_handle.getParam("topics/altitude", altitude_topic); node_handle.getParam("topics/altitude", altitude_topic);
node_handle.getParam("type/altitude", altitude_type); m_smTopic_infos.insert(pair<std::string, std::string>(altitude_topic, "std_msgs/Float64"));
m_smTopic_infos.insert(
pair<std::string, std::string>(altitude_topic, altitude_type));
/*Obtain fc client name from parameter server*/ // Obtain required topic and service names from the parameter server
if (node_handle.getParam("topics/fcclient", fcclient_name)) if (node_handle.getParam("topics/fcclient", fcclient_name))
; ;
else { else
{
ROS_ERROR("Provide a fc client name in Launch file"); ROS_ERROR("Provide a fc client name in Launch file");
system("rosnode kill rosbuzz_node"); system("rosnode kill rosbuzz_node");
} }
if (node_handle.getParam("topics/setpoint", setpoint_name)) if (node_handle.getParam("topics/setpoint", setpoint_name))
; ;
else { else
{
ROS_ERROR("Provide a Set Point name in Launch file"); ROS_ERROR("Provide a Set Point name in Launch file");
system("rosnode kill rosbuzz_node"); system("rosnode kill rosbuzz_node");
} }
if (node_handle.getParam("topics/armclient", armclient)) if (node_handle.getParam("topics/armclient", armclient))
; ;
else { else
{
ROS_ERROR("Provide an arm client name in Launch file"); ROS_ERROR("Provide an arm client name in Launch file");
system("rosnode kill rosbuzz_node"); system("rosnode kill rosbuzz_node");
} }
if (node_handle.getParam("topics/modeclient", modeclient)) if (node_handle.getParam("topics/modeclient", modeclient))
; ;
else { else
{
ROS_ERROR("Provide a mode client name in Launch file"); ROS_ERROR("Provide a mode client name in Launch file");
system("rosnode kill rosbuzz_node"); system("rosnode kill rosbuzz_node");
} }
if (node_handle.getParam("topics/stream", stream_client_name)) if (node_handle.getParam("topics/stream", stream_client_name))
; ;
else { else
{
ROS_ERROR("Provide a mode client name in Launch file"); ROS_ERROR("Provide a mode client name in Launch file");
system("rosnode kill rosbuzz_node"); system("rosnode kill rosbuzz_node");
} }
if (node_handle.getParam("topics/localpos", local_pos_sub_name)) if (node_handle.getParam("topics/localpos", local_pos_sub_name))
; ;
else { else
{
ROS_ERROR("Provide a localpos name in YAML file"); ROS_ERROR("Provide a localpos name in YAML file");
system("rosnode kill rosbuzz_node"); system("rosnode kill rosbuzz_node");
} }
@ -405,33 +460,29 @@ void roscontroller::Initialize_pub_sub(ros::NodeHandle &n_c)
Subscribe(n_c); Subscribe(n_c);
payload_sub = payload_sub = n_c.subscribe(in_payload, 5, &roscontroller::payload_obt, this);
n_c.subscribe(in_payload, 5, &roscontroller::payload_obt, this);
obstacle_sub = n_c.subscribe(obstacles_topic, 5, obstacle_sub = n_c.subscribe(obstacles_topic, 5, &roscontroller::obstacle_dist, this);
&roscontroller::obstacle_dist, this);
/*publishers*/ /*publishers*/
payload_pub = n_c.advertise<mavros_msgs::Mavlink>(out_payload, 5); payload_pub = n_c.advertise<mavros_msgs::Mavlink>(out_payload, 5);
MPpayload_pub = n_c.advertise<mavros_msgs::Mavlink>("fleet_status", 5); MPpayload_pub = n_c.advertise<mavros_msgs::Mavlink>("fleet_status", 5);
neigh_pos_pub = n_c.advertise<rosbuzz::neigh_pos>("neighbours_pos", 5); neigh_pos_pub = n_c.advertise<rosbuzz::neigh_pos>("neighbours_pos", 5);
localsetpoint_nonraw_pub = localsetpoint_nonraw_pub = n_c.advertise<geometry_msgs::PoseStamped>(setpoint_name, 5);
n_c.advertise<geometry_msgs::PoseStamped>(setpoint_name, 5);
/* Service Clients*/ /* Service Clients*/
arm_client = n_c.serviceClient<mavros_msgs::CommandBool>(armclient); arm_client = n_c.serviceClient<mavros_msgs::CommandBool>(armclient);
mode_client = n_c.serviceClient<mavros_msgs::SetMode>(modeclient); mode_client = n_c.serviceClient<mavros_msgs::SetMode>(modeclient);
mav_client = n_c.serviceClient<mavros_msgs::CommandLong>(fcclient_name); mav_client = n_c.serviceClient<mavros_msgs::CommandLong>(fcclient_name);
if (rcclient == true) if (rcclient == true)
service = service = n_c.advertiseService(rcservice_name, &roscontroller::rc_callback, this);
n_c.advertiseService(rcservice_name, &roscontroller::rc_callback, this);
ROS_INFO("Ready to receive Mav Commands from RC client"); ROS_INFO("Ready to receive Mav Commands from RC client");
xbeestatus_srv = n_c.serviceClient<mavros_msgs::ParamGet>(xbeesrv_name); xbeestatus_srv = n_c.serviceClient<mavros_msgs::ParamGet>(xbeesrv_name);
stream_client = capture_srv = n_c.serviceClient<mavros_msgs::CommandBool>(capture_srv_name);
n_c.serviceClient<mavros_msgs::StreamRate>(stream_client_name); stream_client = n_c.serviceClient<mavros_msgs::StreamRate>(stream_client_name);
users_sub = n_c.subscribe("users_pos", 5, &roscontroller::users_pos, this); users_sub = n_c.subscribe("users_pos", 5, &roscontroller::users_pos, this);
local_pos_sub = n_c.subscribe(local_pos_sub_name, 5, local_pos_sub = n_c.subscribe(local_pos_sub_name, 5, &roscontroller::local_pos_callback, this);
&roscontroller::local_pos_callback, this);
multi_msg = true; multi_msg = true;
} }
@ -444,20 +495,15 @@ void roscontroller::Subscribe(ros::NodeHandle &n_c)
m_smTopic_infos.begin(); m_smTopic_infos.begin();
it != m_smTopic_infos.end(); ++it) { it != m_smTopic_infos.end(); ++it) {
if (it->second == "mavros_msgs/ExtendedState") { if (it->second == "mavros_msgs/ExtendedState") {
flight_status_sub = n_c.subscribe( flight_estatus_sub = n_c.subscribe(it->first, 5, &roscontroller::flight_extended_status_update, this);
it->first, 100, &roscontroller::flight_extended_status_update, this);
} else if (it->second == "mavros_msgs/State") { } else if (it->second == "mavros_msgs/State") {
flight_status_sub = n_c.subscribe( flight_status_sub = n_c.subscribe(it->first, 5, &roscontroller::flight_status_update, this);
it->first, 100, &roscontroller::flight_status_update, this);
} else if (it->second == "mavros_msgs/BatteryStatus") { } else if (it->second == "mavros_msgs/BatteryStatus") {
battery_sub = battery_sub = n_c.subscribe(it->first, 5, &roscontroller::battery, this);
n_c.subscribe(it->first, 5, &roscontroller::battery, this);
} else if (it->second == "sensor_msgs/NavSatFix") { } else if (it->second == "sensor_msgs/NavSatFix") {
current_position_sub = current_position_sub = n_c.subscribe(it->first, 5, &roscontroller::current_pos, this);
n_c.subscribe(it->first, 5, &roscontroller::current_pos, this);
} else if (it->second == "std_msgs/Float64") { } else if (it->second == "std_msgs/Float64") {
relative_altitude_sub = relative_altitude_sub = n_c.subscribe(it->first, 5, &roscontroller::current_rel_alt, this);
n_c.subscribe(it->first, 5, &roscontroller::current_rel_alt, this);
} }
std::cout << "Subscribed to: " << it->first << endl; std::cout << "Subscribed to: " << it->first << endl;
@ -469,31 +515,17 @@ void roscontroller::Subscribe(ros::NodeHandle &n_c)
/-------------------------------------------------------*/ /-------------------------------------------------------*/
std::string roscontroller::Compile_bzz(std::string bzzfile_name) std::string roscontroller::Compile_bzz(std::string bzzfile_name)
{ {
/*TODO: change to bzzc instead of bzzparse and also add -I for includes*/
/*Compile the buzz code .bzz to .bo*/ /*Compile the buzz code .bzz to .bo*/
stringstream bzzfile_in_compile; stringstream bzzfile_in_compile;
std::string path = std::string path =
bzzfile_name.substr(0, bzzfile_name.find_last_of("\\/")) + "/"; bzzfile_name.substr(0, bzzfile_name.find_last_of("\\/")) + "/";
// bzzfile_in_compile << path << "/";
// path = bzzfile_in_compile.str();
// bzzfile_in_compile.str("");
std::string name = bzzfile_name.substr(bzzfile_name.find_last_of("/\\") + 1); std::string name = bzzfile_name.substr(bzzfile_name.find_last_of("/\\") + 1);
name = name.substr(0, name.find_last_of(".")); name = name.substr(0, name.find_last_of("."));
bzzfile_in_compile << "bzzc -I " << path bzzfile_in_compile << "bzzc -I " << path
<< "include/"; //<<" "<<path<< name<<".basm"; << "include/";
// bzzfile_in_compile.str("");
// bzzfile_in_compile <<"bzzasm "<<path<<name<<".basm "<<path<<name<<".bo
// "<<path<<name<<".bdbg";
// system(bzzfile_in_compile.str().c_str());
// bzzfile_in_compile.str("");
bzzfile_in_compile << " -b " << path << name << ".bo"; bzzfile_in_compile << " -b " << path << name << ".bo";
// bcfname = bzzfile_in_compile.str();
// std::string tmp_bcfname = path + name + ".bo";
// bzzfile_in_compile.str("");
bzzfile_in_compile << " -d " << path << name << ".bdb "; bzzfile_in_compile << " -d " << path << name << ".bdb ";
// bzzfile_in_compile << " -a " << path << name << ".asm ";
bzzfile_in_compile << bzzfile_name; bzzfile_in_compile << bzzfile_name;
// std::string tmp_dbgfname = path + name + ".bdb";
ROS_WARN("Launching buzz compilation: %s", bzzfile_in_compile.str().c_str()); ROS_WARN("Launching buzz compilation: %s", bzzfile_in_compile.str().c_str());
@ -589,12 +621,15 @@ void roscontroller::prepare_msg_and_publish()
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;
/*Log out message id and message size*/
log<<(int)message_number<<",";
log<<(int)out[0]<<",";
/*publish prepared messages in respective topic*/ /*publish prepared messages in respective topic*/
payload_pub.publish(payload_out); payload_pub.publish(payload_out);
delete[] out; delete[] out;
delete[] payload_out_ptr; delete[] payload_out_ptr;
/*Check for updater message if present send*/ /*Check for updater message if present send*/
if ((int)get_update_mode() != CODE_RUNNING && is_msg_present() == 1 && /* if ((int)get_update_mode() != CODE_RUNNING && is_msg_present() == 1 &&
multi_msg) multi_msg)
{ {
uint8_t *buff_send = 0; uint8_t *buff_send = 0;
@ -636,7 +671,7 @@ void roscontroller::prepare_msg_and_publish()
payload_pub.publish(update_packets); payload_pub.publish(update_packets);
multi_msg = false; multi_msg = false;
delete[] payload_64; delete[] payload_64;
} }*/
} }
/*--------------------------------------------------------------------------------- /*---------------------------------------------------------------------------------
/Flight controller service call every step if there is a command set from bzz /Flight controller service call every step if there is a command set from bzz
@ -646,19 +681,33 @@ script
void roscontroller::flight_controller_service_call() void roscontroller::flight_controller_service_call()
{ {
/* flight controller client call if requested from Buzz*/ /* flight controller client call if requested from Buzz*/
/*FC call for takeoff,land, gohome and arm/disarm*/ double *goto_pos;
int tmp = buzzuav_closures::bzz_cmd(); float *gimbal;
double *goto_pos = buzzuav_closures::getgoto(); switch (buzzuav_closures::bzz_cmd()) {
if (tmp == buzzuav_closures::COMMAND_TAKEOFF ||
tmp == buzzuav_closures::COMMAND_LAND || case buzzuav_closures::COMMAND_TAKEOFF:
tmp == buzzuav_closures::COMMAND_GOHOME) { goto_pos = buzzuav_closures::getgoto();
cmd_srv.request.param7 = goto_pos[2]; cmd_srv.request.param7 = goto_pos[2];
cmd_srv.request.command = buzzuav_closures::getcmd(); cmd_srv.request.command = buzzuav_closures::getcmd();
// std::cout << " CMD: " << buzzuav_closures::getcmd() << std::endl; if (!armstate) {
// SOLO SPECIFIC: SITL DOES NOT USE 21 TO LAND -- workaround: set to LAND SetMode("LOITER", 0);
// mode armstate = 1;
switch (buzzuav_closures::getcmd()) { Arm();
case mavros_msgs::CommandCode::NAV_LAND: ros::Duration(0.5).sleep();
// Registering HOME POINT.
home = cur_pos;
}
if (current_mode != "GUIDED")
SetMode("GUIDED", 2000); // for real solo, just add 2000ms delay (it
// should always be in loiter after arm/disarm)
if (mav_client.call(cmd_srv)) {
ROS_INFO("Reply: %ld", (long int)cmd_srv.response.success);
} else
ROS_ERROR("Failed to call service from flight controller");
break;
case buzzuav_closures::COMMAND_LAND:
cmd_srv.request.command = buzzuav_closures::getcmd();
if (current_mode != "LAND") { if (current_mode != "LAND") {
SetMode("LAND", 0); SetMode("LAND", 0);
armstate = 0; armstate = 0;
@ -671,60 +720,80 @@ void roscontroller::flight_controller_service_call()
} }
armstate = 0; armstate = 0;
break; break;
case mavros_msgs::CommandCode::NAV_TAKEOFF:
if (!armstate) {
SetMode("LOITER", 0); case buzzuav_closures::COMMAND_GOHOME: // NOT FULLY IMPLEMENTED/TESTED !!!
armstate = 1; cmd_srv.request.param5 = home.latitude;
Arm(); cmd_srv.request.param6 = home.longitude;
ros::Duration(0.5).sleep(); cmd_srv.request.param7 = home.altitude;
// Registering HOME POINT. cmd_srv.request.command = buzzuav_closures::getcmd();
home = cur_pos; if (mav_client.call(cmd_srv)) {
} ROS_INFO("Reply: %ld", (long int)cmd_srv.response.success);
if (current_mode != "GUIDED") } else
SetMode("GUIDED", 2000); // for real solo, just add 2000ms delay (it ROS_ERROR("Failed to call service from flight controller");
// should always be in loiter after arm/disarm) break;
case buzzuav_closures::COMMAND_GOTO: // NOT FULLY IMPLEMENTED/TESTED !!!
goto_pos = buzzuav_closures::getgoto();
cmd_srv.request.param5 = goto_pos[0];
cmd_srv.request.param6 = goto_pos[1];
cmd_srv.request.param7 = goto_pos[2];
cmd_srv.request.command = buzzuav_closures::getcmd();
if (mav_client.call(cmd_srv)) {
ROS_INFO("Reply: %ld", (long int)cmd_srv.response.success);
} else
ROS_ERROR("Failed to call service from flight controller");
cmd_srv.request.command = mavros_msgs::CommandCode::CMD_MISSION_START;
if (mav_client.call(cmd_srv)) { if (mav_client.call(cmd_srv)) {
ROS_INFO("Reply: %ld", (long int)cmd_srv.response.success); ROS_INFO("Reply: %ld", (long int)cmd_srv.response.success);
} else } else
ROS_ERROR("Failed to call service from flight controller"); ROS_ERROR("Failed to call service from flight controller");
break; break;
}
} else if (tmp == buzzuav_closures::COMMAND_GOTO) { /*FC call for goto*/ case buzzuav_closures::COMMAND_ARM:
/*prepare the goto publish message */ if (!armstate) {
cmd_srv.request.param5 = goto_pos[0]; SetMode("LOITER", 0);
cmd_srv.request.param6 = goto_pos[1]; armstate = 1;
cmd_srv.request.param7 = goto_pos[2]; Arm();
cmd_srv.request.command = buzzuav_closures::getcmd(); }
if (mav_client.call(cmd_srv)) { break;
ROS_INFO("Reply: %ld", (long int)cmd_srv.response.success);
} else
ROS_ERROR("Failed to call service from flight controller");
cmd_srv.request.command = mavros_msgs::CommandCode::CMD_MISSION_START;
if (mav_client.call(cmd_srv)) {
ROS_INFO("Reply: %ld", (long int)cmd_srv.response.success);
} else
ROS_ERROR("Failed to call service from flight controller");
} else if (tmp == buzzuav_closures::COMMAND_ARM) { /*FC call for arm*/
if (!armstate) {
SetMode("LOITER", 0);
armstate = 1;
Arm();
}
} else if (tmp == buzzuav_closures::COMMAND_DISARM) {
if (armstate) {
armstate = 0;
SetMode("LOITER", 0);
Arm();
}
} else if (tmp == buzzuav_closures::COMMAND_MOVETO) { /*Buzz call for moveto*/
roscontroller::SetLocalPosition(goto_pos[0], goto_pos[1], goto_pos[2], 0);
// roscontroller::SetLocalPositionNonRaw(goto_pos[1], goto_pos[0], case buzzuav_closures::COMMAND_DISARM:
// goto_pos[2], 0); if (armstate) {
armstate = 0;
SetMode("LOITER", 0);
Arm();
}
break;
case buzzuav_closures::COMMAND_MOVETO:
goto_pos = buzzuav_closures::getgoto();
roscontroller::SetLocalPosition(goto_pos[0], goto_pos[1], goto_pos[2], 0);
break;
case buzzuav_closures::COMMAND_GIMBAL:
gimbal = buzzuav_closures::getgimbal();
cmd_srv.request.param1 = gimbal[0];
cmd_srv.request.param2 = gimbal[1];
cmd_srv.request.param3 = gimbal[2];
cmd_srv.request.param4 = gimbal[3];
cmd_srv.request.command = mavros_msgs::CommandCode::CMD_DO_MOUNT_CONTROL;
if (mav_client.call(cmd_srv)) {
ROS_INFO("Reply: %ld", (long int)cmd_srv.response.success);
} else
ROS_ERROR("Failed to call service from flight controller");
break;
case buzzuav_closures::COMMAND_PICTURE:
ROS_INFO("TAKING A PICTURE HERE!! --------------");
mavros_msgs::CommandBool capture_command;
if (capture_srv.call(capture_command)) {
ROS_INFO("Reply: %ld", (long int)capture_command.response.success);
} else
ROS_ERROR("Failed to call service from camera streamer");
break;
} }
} }
/*---------------------------------------------- /*----------------------------------------------
/Refresh neighbours Position for every ten step /Refresh neighbours Position for every ten step
/---------------------------------------------*/ /---------------------------------------------*/
@ -774,39 +843,6 @@ void roscontroller::set_cur_pos(double latitude, double longitude,
/ Compute Range and Bearing of a neighbor in a local reference frame / Compute Range and Bearing of a neighbor in a local reference frame
/ from GPS coordinates / from GPS coordinates
----------------------------------------------------------- */ ----------------------------------------------------------- */
void ecef2ned_matrix(const double ref_ecef[3], double M[3][3]) {
double hyp_az, hyp_el;
double sin_el, cos_el, sin_az, cos_az;
/* Convert reference point to spherical earth centered coordinates. */
hyp_az = sqrt(ref_ecef[0] * ref_ecef[0] + ref_ecef[1] * ref_ecef[1]);
hyp_el = sqrt(hyp_az * hyp_az + ref_ecef[2] * ref_ecef[2]);
sin_el = ref_ecef[2] / hyp_el;
cos_el = hyp_az / hyp_el;
sin_az = ref_ecef[1] / hyp_az;
cos_az = ref_ecef[0] / hyp_az;
M[0][0] = -sin_el * cos_az;
M[0][1] = -sin_el * sin_az;
M[0][2] = cos_el;
M[1][0] = -sin_az;
M[1][1] = cos_az;
M[1][2] = 0.0;
M[2][0] = -cos_el * cos_az;
M[2][1] = -cos_el * sin_az;
M[2][2] = -sin_el;
}
void matrix_multiply(uint32_t n, uint32_t m, uint32_t p, const double *a,
const double *b, double *c) {
uint32_t i, j, k;
for (i = 0; i < n; i++)
for (j = 0; j < p; j++) {
c[p * i + j] = 0;
for (k = 0; k < m; k++)
c[p * i + j] += a[m * i + k] * b[p * k + j];
}
}
float roscontroller::constrainAngle(float x) { float roscontroller::constrainAngle(float x) {
x = fmod(x,2*M_PI); x = fmod(x,2*M_PI);
if (x < 0.0) if (x < 0.0)
@ -940,18 +976,10 @@ void roscontroller::SetLocalPosition(float x, float y, float z, float yaw) {
moveMsg.header.stamp = ros::Time::now(); moveMsg.header.stamp = ros::Time::now();
moveMsg.header.seq = setpoint_counter++; moveMsg.header.seq = setpoint_counter++;
moveMsg.header.frame_id = 1; moveMsg.header.frame_id = 1;
// float ned_x, ned_y;
// gps_ned_home(ned_x, ned_y);
// ROS_INFO("[%i] ROSBuzz Home: %.7f, %.7f", robot_id, home[0],
// home[1]);
// ROS_INFO("[%i] ROSBuzz LocalPos: %.7f, %.7f", robot_id,
// local_pos[0], local_pos[1]);
/*prepare the goto publish message ATTENTION: ENU FRAME FOR MAVROS STANDARD //ROS_INFO("Lp: %.3f, %.3f - Del: %.3f, %.3f", local_pos_new[0], local_pos_new[1], x, y);
* (then converted to NED)*/ moveMsg.pose.position.x = local_pos_new[0] + y;
// target[0]+=y; target[1]+=x; moveMsg.pose.position.y = local_pos_new[1] + x;
moveMsg.pose.position.x = local_pos_new[0] + y; // ned_y+y;
moveMsg.pose.position.y = local_pos_new[1] + x; // ned_x+x;
moveMsg.pose.position.z = z; moveMsg.pose.position.z = z;
moveMsg.pose.orientation.x = 0; moveMsg.pose.orientation.x = 0;
@ -977,7 +1005,7 @@ void roscontroller::SetMode(std::string mode, int delay_miliseconds) {
set_mode_message.request.custom_mode = mode; set_mode_message.request.custom_mode = mode;
current_mode = mode; current_mode = mode;
if (mode_client.call(set_mode_message)) { if (mode_client.call(set_mode_message)) {
ROS_INFO("Set Mode Service call successful!"); ;//ROS_INFO("Set Mode Service call successful!");
} else { } else {
ROS_INFO("Set Mode Service call failed!"); ROS_INFO("Set Mode Service call failed!");
} }
@ -993,7 +1021,7 @@ void roscontroller::SetStreamRate(int id, int rate, int on_off) {
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();
} }
ROS_INFO("Set stream rate call successful"); //ROS_INFO("Set stream rate call successful");
} }
/*------------------------------------------------------------- /*-------------------------------------------------------------
@ -1059,13 +1087,10 @@ void roscontroller::payload_obt(const mavros_msgs::Mavlink::ConstPtr &msg) {
nei_pos.longitude = neighbours_pos_payload[1]; nei_pos.longitude = neighbours_pos_payload[1];
nei_pos.altitude = neighbours_pos_payload[2]; nei_pos.altitude = neighbours_pos_payload[2];
double cvt_neighbours_pos_payload[3]; double cvt_neighbours_pos_payload[3];
// cout<<"Got" << neighbours_pos_payload[0] <<", " <<
//neighbours_pos_payload[1] << ", " << neighbours_pos_payload[2] << endl;
gps_rb(nei_pos, cvt_neighbours_pos_payload); gps_rb(nei_pos, cvt_neighbours_pos_payload);
/*Extract robot id of the neighbour*/ /*Extract robot id of the neighbour*/
uint16_t *out = buzz_utility::u64_cvt_u16((uint64_t) * (message_obt + 3)); uint16_t *out = buzz_utility::u64_cvt_u16((uint64_t) * (message_obt + 3));
ROS_WARN("RAB of %i: %f, %f", (int)out[1], cvt_neighbours_pos_payload[0], if(debug) ROS_WARN("RAB of %i: %f, %f", (int)out[1], cvt_neighbours_pos_payload[0], cvt_neighbours_pos_payload[1]);
cvt_neighbours_pos_payload[1]);
/*pass neighbour position to local maintaner*/ /*pass neighbour position to local maintaner*/
buzz_utility::Pos_struct n_pos(cvt_neighbours_pos_payload[0], buzz_utility::Pos_struct n_pos(cvt_neighbours_pos_payload[0],
cvt_neighbours_pos_payload[1], cvt_neighbours_pos_payload[1],
@ -1089,58 +1114,62 @@ bool roscontroller::rc_callback(mavros_msgs::CommandLong::Request &req,
mavros_msgs::CommandLong::Response &res) { mavros_msgs::CommandLong::Response &res) {
int rc_cmd; int rc_cmd;
switch (req.command) { switch (req.command) {
case mavros_msgs::CommandCode::NAV_TAKEOFF: case mavros_msgs::CommandCode::NAV_TAKEOFF:
ROS_INFO("RC_call: TAKE OFF!!!!"); ROS_INFO("RC_call: TAKE OFF!!!!");
rc_cmd = mavros_msgs::CommandCode::NAV_TAKEOFF; rc_cmd = mavros_msgs::CommandCode::NAV_TAKEOFF;
buzzuav_closures::rc_call(rc_cmd);
res.success = true;
break;
case mavros_msgs::CommandCode::NAV_LAND:
ROS_INFO("RC_Call: LAND!!!! sending land");
rc_cmd = mavros_msgs::CommandCode::NAV_LAND;
buzzuav_closures::rc_call(rc_cmd);
res.success = true;
break;
case mavros_msgs::CommandCode::CMD_COMPONENT_ARM_DISARM:
rc_cmd = mavros_msgs::CommandCode::CMD_COMPONENT_ARM_DISARM;
armstate = req.param1;
if (armstate) {
ROS_INFO("RC_Call: ARM!!!!");
buzzuav_closures::rc_call(rc_cmd); buzzuav_closures::rc_call(rc_cmd);
res.success = true; res.success = true;
} else { break;
ROS_INFO("RC_Call: DISARM!!!!"); case mavros_msgs::CommandCode::NAV_LAND:
buzzuav_closures::rc_call(rc_cmd + 1); ROS_INFO("RC_Call: LAND!!!!");
rc_cmd = mavros_msgs::CommandCode::NAV_LAND;
buzzuav_closures::rc_call(rc_cmd);
res.success = true; res.success = true;
} break;
break; case mavros_msgs::CommandCode::CMD_COMPONENT_ARM_DISARM:
case mavros_msgs::CommandCode::NAV_RETURN_TO_LAUNCH: rc_cmd = mavros_msgs::CommandCode::CMD_COMPONENT_ARM_DISARM;
ROS_INFO("RC_Call: GO HOME!!!!"); armstate = req.param1;
rc_cmd = mavros_msgs::CommandCode::NAV_RETURN_TO_LAUNCH; if (armstate) {
buzzuav_closures::rc_call(rc_cmd); ROS_INFO("RC_Call: ARM!!!!");
res.success = true; buzzuav_closures::rc_call(rc_cmd);
break; res.success = true;
case mavros_msgs::CommandCode::NAV_WAYPOINT: } else {
ROS_INFO("RC_Call: GO TO!!!! --- Doing this! "); ROS_INFO("RC_Call: DISARM!!!!");
double rc_goto[3]; buzzuav_closures::rc_call(rc_cmd + 1);
// testing PositionTarget res.success = true;
rc_goto[0] = req.param5; }
rc_goto[1] = req.param6; break;
rc_goto[2] = req.param7; case mavros_msgs::CommandCode::NAV_RETURN_TO_LAUNCH:
buzzuav_closures::rc_set_goto(rc_goto); ROS_INFO("RC_Call: GO HOME!!!!");
rc_cmd = mavros_msgs::CommandCode::NAV_WAYPOINT; rc_cmd = mavros_msgs::CommandCode::NAV_RETURN_TO_LAUNCH;
buzzuav_closures::rc_call(rc_cmd); buzzuav_closures::rc_call(rc_cmd);
res.success = true; res.success = true;
break; break;
case 666: case mavros_msgs::CommandCode::NAV_WAYPOINT:
ROS_INFO("RC_Call: Update Fleet Status!!!!"); ROS_INFO("RC_Call: GO TO!!!! ");
rc_cmd = 666; buzzuav_closures::rc_set_goto(req.param1,req.param5,req.param6,req.param7);
buzzuav_closures::rc_call(rc_cmd); rc_cmd = mavros_msgs::CommandCode::NAV_WAYPOINT;
res.success = true; buzzuav_closures::rc_call(rc_cmd);
break; res.success = true;
default: break;
res.success = false; case mavros_msgs::CommandCode::CMD_DO_MOUNT_CONTROL:
break; ROS_INFO("RC_Call: Gimbal!!!! ");
buzzuav_closures::rc_set_gimbal(req.param1,req.param2,req.param3,req.param4,req.param5);
rc_cmd = mavros_msgs::CommandCode::CMD_DO_MOUNT_CONTROL;
buzzuav_closures::rc_call(rc_cmd);
res.success = true;
break;
case CMD_REQUEST_UPDATE:
//ROS_INFO("RC_Call: Update Fleet Status!!!!");
rc_cmd = CMD_REQUEST_UPDATE;
buzzuav_closures::rc_call(rc_cmd);
res.success = true;
break;
default:
buzzuav_closures::rc_call(req.command);
ROS_INFO("----> Received unregistered command: ", req.command);
res.success = true;
break;
} }
return true; return true;
} }