我已经实现了一个具有 4 个节点拓扑的本地化算法,它工作正常,但是在日志文件中我收到了这个错误,我无法理解问题出在哪里。算法卡住了一段时间,出现此错误,然后再次恢复正常流程。如何消除此错误?
Exception in agent: simulator
java.lang.NullPointerException: Cannot get property 'location' on null object
Stack trace: ...
org.arl.unet.sim.SimulationAgent$_doMotion_closure1.doCall(initrc.groovy:236)
jdk.internal.reflect.GeneratedMethodAccessor103.invoke(Unknown Source)
java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ...
org.arl.unet.sim.SimulationAgent.doMotion(initrc.groovy:235)
java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ...
org.arl.unet.sim.SimulationAgent.this$dist$invoke$2(initrc.groovy)
org.arl.unet.sim.SimulationAgent$3.methodMissing(initrc.groovy)
jdk.internal.reflect.GeneratedMethodAccessor201.invoke(Unknown Source)
java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ...
org.arl.unet.sim.SimulationAgent$3.onExpiry(initrc.groovy:227)
org.arl.fjage.BackoffBehavior.action(BackoffBehavior.java:90)
org.arl.fjage.Agent.executeBehavior(Agent.java:774)
org.arl.fjage.Agent.run(Agent.java:811) ...
以下是我的脚本:
模拟.groovy
import org.arl.fjage.*
println '''
3-node network
--------------
'''
platform = RealTimePlatform
simulate {
def m=node 'B', address:107, location: [-600.m, -22.m, -15.m], web:8081,api: 1101, shell:
true, mobility:true,stack: "$home/etc/setup2"
m.motionModel=[ [duration:1.minutes, speed:0.mps, heading:100.deg],
[time:1.minutes, duration:3.minutes, speed:1.mps, heading:100.deg]
]
node 'n1', address: 101, location: [900.m, 900.m, -15.m], web:8082,api: 1102, shell: 5101,
stack: "$home/etc/setup3"
node 'n2', address: 102, location: [-900.m, 900.m, -15.m], web:8083,api: 1103, shell: 5102,
stack: "$home/etc/setup3"
node 'n3', address: 103, location: [ -900.m, -800.m, -15.m], web:8084,api: 1104, shell: 5103,
stack: "$home/etc/setup3"
}
锚代理.groovy
import org.arl.fjage.*
import org.arl.fjage.Message
import org.arl.fjage.RealTimePlatform
import org.arl.unet.phy.*
import org.arl.unet.mac.*
import org.arl.unet.*
import org.arl.unet.PDU
import org.arl.unet.net.Router
import org.arl.unet.nodeinfo.NodeInfo
import org.arl.unet.localization.*
import org.arl.unet.localization.RangeNtf.*
import org.arl.unet.localization.Ranging.*
import org.arl.unet.localization.RangeReq
import org.arl.unet.net.RouteDiscoveryReq
class anchor_agent extends UnetAgent {
def addr;
def nme;
def phy;
def nodeInfo;
private final static PDU format = PDU.withFormat
{
uint16('source');
}
void startup()
{
def phy = agentForService Services.PHYSICAL;
subscribe topic(phy);
nodeInfo = agentForService Services.NODE_INFO;
}
void processMessage(Message msg)
{
phy = agentForService Services.PHYSICAL;
subscribe topic(phy);
addr = nodeInfo.address;
nme = nodeInfo.nodeName;
def datapacket = format.encode(source: addr);
if(msg instanceof DatagramNtf && msg.protocol==Protocol.MAC)
{
def n=rndint(4);
def k=rndint(5);
// def l=rndint(4);
def delay=(n+1)*(k+1);
println "Broadcast packet received at node "+nme;
println "Node "+nme+" will respond after "+ delay +" seconds"
println ' '
add new WakerBehavior(delay*1000,{
phy << new TxFrameReq(to: msg.from,
protocol: Protocol.MAC,
data: datapacket)
})
}
}
}
node_agent.groovy
import org.arl.fjage.*
import org.arl.fjage.Message
import org.arl.fjage.RealTimePlatform
import org.arl.unet.phy.*
import org.arl.unet.mac.*
import org.arl.unet.*
import org.arl.unet.PDU
import org.arl.unet.net.Router
import org.arl.unet.nodeinfo.NodeInfo
import org.arl.unet.localization.*
import org.arl.unet.localization.RangeNtf.*
import org.arl.unet.localization.Ranging.*
import org.arl.unet.localization.RangeReq
import org.arl.unet.net.RouteDiscoveryReq
import groovy.time.TimeCategory
import groovy.time.TimeDuration
class node_agent extends UnetAgent {
float neighbor_addr;
float distance;
def ranging;
def nodeInfo;
def start;
def stop;
def nos=0;
def xlist = [];
def ylist = [];
def zlist = [];
def dlist = [];
def adlist = [];
private final static PDU format = PDU.withFormat
{
uint16('source')
}
void startup()
{
def phy = agentForService Services.PHYSICAL;
subscribe topic(phy);
ranging = agentForService Services.RANGING;
subscribe topic(ranging);
nodeInfo = agentForService Services.NODE_INFO;
println 'Starting discovery...'
start = currentTimeMillis() ;
xlist.clear();
ylist.clear();
zlist.clear();
dlist.clear();
adlist.clear();
phy << new DatagramReq(to: 0, protocol:Protocol.MAC);
add new TickerBehavior(120000, {
nos=0;
xlist.clear();
ylist.clear();
zlist.clear();
dlist.clear();
adlist.clear();
println 'Starting discovery...'
start = currentTimeMillis() ;
phy << new DatagramReq(to: 0, protocol:Protocol.MAC);
})
}
void processMessage(Message msg)
{
if(msg instanceof RxFrameNtf && msg.protocol==Protocol.MAC && nos<3)
{
nos++;
def rx = format.decode(msg.data);
neighbor_addr=rx.source;
println "Found one anchor with address "+neighbor_addr;
adlist.add(neighbor_addr)
println adlist;
if(adlist.size()==3) //As soon as I get the address of 3 neighbour
{ //nodes query the range and coordinates information.
println "Found 3 anchor nodes, getting locations....";
println ' '
def i=0;
float n1=adlist[0];
float n2=adlist[1];
float n3=adlist[2];
//waker behavior to avoid collision in RangeNtf
add new WakerBehavior(0,{
ranging<< new RangeReq(to: n1,requestLocation: true)})
add new WakerBehavior(7000,{
ranging<< new RangeReq(to: n2,requestLocation: true)})
add new WakerBehavior(14000,{
ranging<< new RangeReq(to: n3,requestLocation: true)})
}
}
else if (msg instanceof RangeNtf )
{
distance = msg.getRange();
def locat=new double[3];
locat = msg.getPeerLocation();
double x,y,z;
x=locat[0];
y=locat[1];
z=locat[2];
xlist.add(x);
ylist.add(y);
zlist.add(z);
dlist.add(distance);
println " The coordinates of "+msg.to + " are " +locat+ " and the distance is "+distance;
if(dlist.size()==3)
{
println ' '
println 'x-coordinates'+ xlist;
println 'y-coordinates'+ ylist;
println 'z-coordinates'+ zlist;
println 'ranges'+ dlist;
BigDecimal X, Y, Va, Vb, Xa, Xb, Xc, Ya, Yb, Yc, Da, Db, Dc, tmp1, tmp2, tmp3, tmp4, tmp5;
Xa = xlist[0]; // Initializing the parameters
Ya = ylist[0];
Xb = xlist[1];
Yb = ylist[1];
Xc = xlist[2];
Yc = ylist[2];
Da = dlist[0];
Db = dlist[1];
Dc = dlist[2];
tmp1=(Math.pow(Xb, 2) - Math.pow(Xa, 2))
tmp2=(Math.pow(Yb, 2) - Math.pow(Ya, 2))
tmp3=(Math.pow(Db, 2) - Math.pow(Da, 2)) // tmp1, tmp2, tmp3 are intermediate variables to avoid overflow
Va = ( tmp1 + tmp2 - tmp3) / 2;
tmp1=(Math.pow(Xb, 2) - Math.pow(Xc, 2))
tmp2=(Math.pow(Yb, 2) - Math.pow(Yc, 2))
tmp3=(Math.pow(Db, 2) - Math.pow(Dc, 2)) // tmp1, tmp2, tmp3 are intermediate variables to avoid overflow
Vb = (tmp1 + tmp2 - tmp3) / 2;
tmp4=(Va * (Yb - Yc) - Vb * (Yb - Ya))
tmp5=((Yb - Yc) * (Xb - Xa) - (Yb - Ya) * (Xb - Xc)) // tmp4, tmp5 are intermediate variables to avoid overflow
X = tmp4 / tmp5;
tmp4=(Va * (Xb - Xc) - Vb * (Xb - Xa))
tmp5=((Yb - Ya) * (Xb - Xc) - (Xb - Xa) * (Yb - Yc)) // tmp4, tmp5 are intermediate variables to avoid overflow
Y = tmp4 / tmp5
X = Math.round(X * 100000) / 100000
Y = Math.round(Y * 100000) / 100000 // precision of upto 5 digits after decimal
println ' '
println 'THE ACTUAL COORDINATES AT THIS INSTANCE ARE '+ nodeInfo.location;
stop = currentTimeMillis() ;
int td = stop - start;
td=td/1000;
def e1=td*0.98480775301;
def e2=td*(-0.17364817766);
///////////////////////////////////////////////////////////
def p=Math.pow((X-(nodeInfo.location[0])),2);
def q=Math.pow((Y-(nodeInfo.location[1])),2);
def r=Math.sqrt(p+q);
r=Math.round(r * 100000) / 100000;
//////////////////////////////////////////////////////////
BigDecimal X1,Y1;
Y1=Y+e2;
X1=X+e1;
def j=Math.pow((X1-(nodeInfo.location[0])),2);
def k=Math.pow((Y1-(nodeInfo.location[1])),2);
def l=Math.sqrt(p+q);
l=Math.round(l * 100000) / 100000;
//////////////////////////////////////////////////////////
if(r < l)
{
println "The coordinates of the Blind node are "
println "("+ X + " , " + Y + " , " + zlist[0] + ")" ;
println "Distance between actual coordinates and estimated coordinates: r ";
println ' '+r;
}
else{
println "The coordinates of the Blind node are "
println "("+ X1 + " , " + Y1 + " , " + zlist[0] + ")" ;
println "Distance between actual coordinates and estimated coordinates: l ";
println ' '+l;
}
println "Total time taken "+td+' seconds';
xlist.clear();
ylist.clear();
zlist.clear();
dlist.clear();
adlist.clear();
}
}
}
}
setup2.groovy
import org.arl.fjage.Agent
boolean loadAgentByClass(String name, String clazz) {
try {
container.add name, Class.forName(clazz).newInstance()
return true
} catch (Exception ex) {
return false
}
}
boolean loadAgentByClass(String name, String... clazzes) {
for (String clazz: clazzes) {
if (loadAgentByClass(name, clazz)) return true
}
return false
}
loadAgentByClass 'arp', 'org.arl.unet.addr.AddressResolution'
loadAgentByClass 'ranging', 'org.arl.unet.localization.Ranging'
loadAgentByClass 'mac', 'org.arl.unet.mac.CSMA'
loadAgentByClass 'uwlink', 'org.arl.unet.link.ECLink', 'org.arl.unet.link.ReliableLink'
loadAgentByClass 'transport', 'org.arl.unet.transport.SWTransport'
loadAgentByClass 'router', 'org.arl.unet.net.Router'
loadAgentByClass 'rdp', 'org.arl.unet.net.RouteDiscoveryProtocol'
loadAgentByClass 'statemanager', 'org.arl.unet.state.StateManager'
//loadAgentByClass 'pri', 'org.arl.unet.UnetAgent.node_agent'
container.add 'remote', new org.arl.unet.remote.RemoteControl(cwd: new File(home, 'scripts'), enable: false)
container.add 'bbmon', new org.arl.unet.bb.BasebandSignalMonitor(new File(home, 'logs/signals-0.txt').path, 64)
container.add 'myagent' , new node_agent()
setup3.groovy
import org.arl.fjage.Agent
boolean loadAgentByClass(String name, String clazz) {
try {
container.add name, Class.forName(clazz).newInstance()
return true
} catch (Exception ex) {
return false
}
}
boolean loadAgentByClass(String name, String... clazzes) {
for (String clazz: clazzes) {
if (loadAgentByClass(name, clazz)) return true
}
return false
}
loadAgentByClass 'arp', 'org.arl.unet.addr.AddressResolution'
loadAgentByClass 'ranging', 'org.arl.unet.localization.Ranging'
loadAgentByClass 'mac', 'org.arl.unet.mac.CSMA'
loadAgentByClass 'uwlink', 'org.arl.unet.link.ECLink', 'org.arl.unet.link.ReliableLink'
loadAgentByClass 'transport', 'org.arl.unet.transport.SWTransport'
loadAgentByClass 'router', 'org.arl.unet.net.Router'
loadAgentByClass 'rdp', 'org.arl.unet.net.RouteDiscoveryProtocol'
loadAgentByClass 'statemanager', 'org.arl.unet.state.StateManager'
container.add 'remote', new org.arl.unet.remote.RemoteControl(cwd: new File(home, 'scripts'), enable: false)
container.add 'bbmon', new org.arl.unet.bb.BasebandSignalMonitor(new File(home, 'logs/signals-0.txt').path, 64)
container.add 'resp_agent' , new anchor_agent()