通讯
通讯设备为许多AFSIM功能奠定了基础,包括远程任务分配、指挥链以及许多其他模拟和建模选项。
这些设备是促进平台之间远程通信的部分。它们在平台之间传输和接收消息,可以是有线或无线。通讯设备必须使用相同的网络进行相互通信。
AFSIM提供了一些预定义的通讯设备,其中最常见的包括:
- WSF_COMM_RCVR
- WSF_COMM_XMTR
- WSF_COMM_TRANSCEIVER
- WSF_RADIO_RCVR
- WSF_RADIO_XMTR
- WSF_RADIO_TRANSCEIVER
快速入门
要开始使用通讯设备,可以将以下comm命令块添加到现有的平台或平台类型中:
comm perfect_transceiver WSF_COMM_TRANSCEIVER
end_comm
任何具有perfect_transceiver的平台都能够默认为彼此通信,从而允许平台在网络上发送消息。通过引入发射器和接收器规格、天线命令、可动部件命令、带宽限制、错误率和信噪比,可以模拟更高保真的通信网络。
可以在处理器中添加内部链接,以实现一个平台与其他平台之间的跟踪通信。
深入了解
请注意,以下步骤假设“simple_flight”场景存在,如“行为与行为树”中所讨论的。
添加通信
要在simple_flight中实现两架飞机之间的通信,请完成以下步骤:
-
创建一个新文件,命名为communications.txt。
-
在cargo_aircraft.txt中添加以下代码行:
nclude_once communications.txt
-
在Wizard文本编辑器中打开communications.txt。
-
将以下代码添加到communications.txt中:
# communications.txt # A component of the simple_flight demo comm AIR_RADIO_TRANSCEIVER WSF_RADIO_TRANSCEIVER transmitter frequency 120 mhz end_transmitter receiver frequency 120 mhz end_receiver end_comm
-
在CARGO_AIRCRAFT的平台注册类型定义中添加以下代码:
add comm atc AIR_RADIO_TRANSCEIVER end_comm
此时,两架飞机之间已经建立了一个开放的通信通道,可以传递消息。然而,它们目前没有要发送的消息。
添加行为和处理器以通过通信发送消息
目前,behaviors.txt中的自动行为将导致每架飞机远离另一架飞机。这并不是必要的,因为只需要其中一架飞机改变高度以避免碰撞就可以了。
1 更新behavior.txt以反映以下内容:
# behaviors.txt
# A component of the simple_flight demo
behavior next_selector
precondition
return true;
end_precondition
end_behavior
behavior all_clear
precondition
WsfLocalTrackList trackList = PLATFORM.TrackList("track_proc");
return (trackList.Empty() && !PLATFORM.AuxDataBool("collisionExpected"));
end_precondition
execute
WsfPlatform plat = PLATFORM;
writeln(plat.Name(), " Report: All Clear");
end_execute
end_behavior
behavior entity_detected
precondition
WsfLocalTrackList trackList = PLATFORM.TrackList("track_proc");
return !trackList.Empty();
end_precondition
execute
WsfPlatform plat = PLATFORM;
WsfTrack firstTrack = plat.TrackList("track_proc")[0];
writeln(plat.Name(), " Report: Entity Detected");
if (!plat.AuxDataBool("collisionWarningRcvd"))
{
plat.SetAuxData("collisionExpected", false);
}
if (plat.AuxDataBool("collisionWarningCooldown"))
{
plat.SetAuxData("collisionWarningCooldown", false);
}
else
{
WsfLocalTrackList trackList = plat.TrackList("track_proc");
int index = 0;
foreach (WsfTrack t in trackList)
{
if (t.Target().IsValid())
{
writeln("\t - Entity: ", t.Target().Name());
double lastDist = plat.AuxDataDouble("lastKnownDistance");
double currDist = plat.GroundRangeTo(t.CurrentLocation());
if (Math.Ceil(plat.Altitude()/100) == Math.Ceil(t.Altitude()/100) &&
(lastDist == -1 || lastDist > currDist))
{
plat.SetAuxData("lastKnownDistance", currDist);
writeln("\t - WARNING: Collision Expected!\n");
plat.SetAuxData("collisionExpected", true);
plat.SetAuxData("collisionTrackIdx", index);
}
else
{
plat.SetAuxData("collisionExpected", false);
}
}
index = index + 1;
}
}
end_execute
end_behavior
behavior reroute
precondition
bool collisionExpected = PLATFORM.AuxDataBool("collisionExpected");
bool collisionWarningRcvd = PLATFORM.AuxDataBool("collisionWarningRcvd");
return (collisionExpected || collisionWarningRcvd);
end_precondition
execute
WsfPlatform plat = PLATFORM;
double altDelta = 100 * Math.Ceil(RANDOM.Uniform(0, 30) - 20);
plat.GoToAltitude(plat.Altitude() + altDelta);
writeln(plat.Name(), " Report: Rerouting");
writeln("\t - New Target Altitude = ", plat.Altitude() + altDelta, "m\n");
plat.SetAuxData("collisionWarningRcvd", false);
plat.SetAuxData("collisionExpected", false);
plat.SetAuxData("offRoute", true);
end_execute
end_behavior
behavior send_warning_message
precondition
bool collisionExpected = PLATFORM.AuxDataBool("collisionExpected");
bool collisionWarningRcvd = PLATFORM.AuxDataBool("collisionWarningRcvd");
bool trackListEmpty = PLATFORM.TrackList("track_proc").Empty();
return (collisionExpected && !collisionWarningRcvd && !trackListEmpty);
end_precondition
execute
WsfPlatform plat = PLATFORM;
if (plat.AuxDataBool("collisionWarningCooldown"))
{
plat.SetAuxData("collisionWarningCooldown", false);
}
else
{
writeln(plat.Name(), " Report: Sending Warning");
WsfLocalTrackList trackList = plat.TrackList("track_proc");
int collisionTrackIdx = plat.AuxDataInt("collisionTrackIdx");
WsfPlatform trackPlat = trackList[collisionTrackIdx].Target();
WsfComm platComm = plat.CommEntry(0);
writeln("\t - Comm: ", platComm.Name());
writeln("\t - Destination: ", trackPlat.Name());
if (trackPlat.CommCount() > 0)
{
WsfComm trackComm = trackPlat.CommEntry(0);
WsfMessage warningMessage = WsfMessage();
warningMessage.SetType("WARNING");
warningMessage.SetSubType("collision-expected");
platComm.SendMessage(warningMessage, trackComm);
writeln("\t - Warning Sent(", warningMessage.Type(), ")");
plat.SetAuxData("collisionWarningCooldown", true);
}
else
{
writeln("\t - Warning Failed: Target has no comms!");
}
}
end_execute
end_behavior
2 更新 CARGO_TASK_MANAGER,如下所示:
processor CARGO_TASK_MANAGER WSF_TASK_PROCESSOR
update_interval 10 sec
behavior_tree
sequence
selector
behavior_node all_clear
behavior_node entity_detected
behavior_node next_selector
end_selector
selector
behavior_node send_warning_message
behavior_node reroute
end_selector
end_sequence
end_behavior_tree
end_processor
3 创建一个 WARNING PROCESSOR,如下所示:
processor WARNING_PROCESSOR WSF_SCRIPT_PROCESSOR
on_message
type WARNING
script
writeln(PLATFORM.Name(), " Report: Message Received");
WsfMessage warningMessage = (WsfMessage)MESSAGE;
writeln("\t - Type: ", warningMessage.Type());
writeln("\t - Subtype: ", warningMessage.SubType());
writeln("\t - Origin: ", warningMessage.Originator());
PLATFORM.SetAuxData("collisionWarningRcvd", true);
PLATFORM.SetAuxData("collisionExpected", true);
end_script
type default
script
writeln(PLATFORM.Name(), "Report: Message Received");
end_script
end_on_message
end_processor
4 将 WARNING_PROCESSOR 添加到 CARGO_AIRCRAFT 的平台类型定义中,如下所示:
add processor warning_proc WARNING_PROCESSOR
end_processor
更新 CARGO_AIRCRAFT 平台类型定义中的 AIR_RADIO_TRANSCEIVER 命令块,如下所示:
add comm atc AIR_RADIO_TRANSCEIVER
internal_link warning_proc
end_comm
更新 CARGO_AIRCRAFT 平台类型定义中的 aux_data 命令块,如下所示:
aux_data
struct CARGO_AUX_DATA
bool collisionExpected = false
bool collisionWarningCooldown = false
bool collisionWarningRcvd = false
int collisionTrackIdx = 0
double lastKnownDistance = -1
end_struct
end_aux_data
最后,在 platform_laydown.txt 中,通过将以下代码添加到 cargo-1 平台定义中来增加 cargo_radar 的范围:
edit sensor cargo_radar
maximum_range 40 nm
end_sensor
这些新增功能将使 cargo-1 拥有更长距离的雷达。当它探测到 cargo-2,并计算出两架飞机处于碰撞航线时,它将生成一条警告消息,并发送给 cargo-2。在接收到消息后,cargo-2 将通过改变高度来重新规划航线,从而避免碰撞,而无需 cargo-1 改变其航线。
总结:
通讯设备是连接平台以共享信息和轨迹的手段。正如快速入门中详细描述的那样,轨迹在平台之间是直观地共享的,但轨迹并不是唯一可以共享的信息。尽管这可能需要脚本、行为、处理器或传感器,几乎可以在平台之间或平台之间传达任何信息。