【仿真建模-anylogic】动态生成ConveyorCustomStation

2024-06-19 02:04

本文主要是介绍【仿真建模-anylogic】动态生成ConveyorCustomStation,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Author:赵志乾
Date:2024-06-18
Declaration:All Right Reserved!!!

0. 背景

        直接使用Anylogic组件开发的模型无法动态改变运输网布局;目前需求是要将运输网布局配置化;运输网配置化的前提是将其标准化为仅包含辊道、自定义站点两种元素的网络;之后依据配置文件动态构建运输网;最后将自定义Agent逻辑关联到自定义站点实现流程串通;本次示例仅包含运输网中的辊道和自定义站点的动态生成以及组装过程;

1. 常用函数

函数功能
ConveyorCustomStation()构造函数
addVertex(double x, double y)添加点以构建2D图形,注意点:需要至少三个点,且连起的图形不得自身有交叉;通常会将CustomStation的图形隐藏,而将其内部自定义逻辑封装成Agent,用Agent的presentation替补CustomStation本身的图形;
addConnection(ConveyorPath conveyor, PathType type)将CustomStation与conveyor连接起来
onEnter(T agent)根据需要定义子类覆写该方法;当所运输物料进入CustomStation时,会自动执行该方法;

2. 数据结构定义

{"points": [{"code": "", // 点编码"name": "", // 点名称"x": 0.0, // 点坐标"y": 0.0,"z": 0.0}],"conveyors": [{"code": "", // 辊道编码"name": "", // 辊道名称"pointCodes": [] // 辊道从起点至终点所经历的位置点编码列表}],"customStations": [{"code": "",     // 自定义站点编码"name": "",     // 自定义站点名称"inConveyorCodes": [], // 传入站点的辊道"outConveyorCodes": [] // 传出站点的辊道}]
}

3. 代码实现

// ************************数据对象定义****************************
public class PointDefinition implements Serializable {private String code;private String name;private Double x;private Double y;private Double z;// setter、getter
}public class ConveyorDefinition implements Serializable {private String code;private String name;// setter、getter
}public class LayoutDefinition implements Serializable {private List<PointDefinition> points;private List<ConveyorDefinition> conveyors;private List<CustomStationDefinition> customStations;// setter、getter
}public class CustomStationDefinition implements Serializable {private String code;private String name;private List<String> inConveyorCodes;private List<String> outConveyorCodes;// setter、getter
}//******************************子类*******************************
public class CustomStation<T extends Agent> extends ConveyorCustomStation<T> {// 持有站点定义,便于onEnter中依据站点不同做不同处理CustomStationDefinition customStationDefinition;public CustomStation(CustomStationDefinition customStationDefinition) {super();this.customStationDefinition = customStationDefinition;}public void onEnter(T agent ) {// 自定义逻辑}
}//**************************动态生成过程******************************
// step1: 转map,方便后续使用
Map<String,PointDefinition> codeToPointDefinitionMap = layoutDefinition.getPoints().stream().collect(Collectors.toMap(PointDefinition::getCode, Function.identity(), (a,b)->b));
Map<String,ConveyorDefinition> codeToConveyorDefinitionMap = layoutDefinition.getConveyors().stream().collect(Collectors.toMap(ConveyorDefinition::getCode, Function.identity(), (a,b)->b));
Map<ConveyorDefinition,ConveyorPath> definitionToConveyorMap = new HashMap<>();// step2: 定义网络对象
ConveyorNetwork conveyorNetwork = new ConveyorNetwork(this,"conveyorNetwork");// step3: 向网络添加conveyor
for(ConveyorDefinition conveyorDefinition : layoutDefinition.getConveyors()){ConveyorPath conveyor = new ConveyorPath();// 每个conveyor由若干段组成for(int index=0; index<conveyorDefinition.getPointCodes().size()-1; index++){PointDefinition startPoint = codeToPointDefinitionMap.get(conveyorDefinition.getPointCodes().get(index));PointDefinition endPoint = codeToPointDefinitionMap.get(conveyorDefinition.getPointCodes().get(index+1));double startX = scale.pixelsPerUnit(METER)*startPoint.getX();double startY = scale.pixelsPerUnit(METER)*startPoint.getY();double startZ = scale.pixelsPerUnit(METER)*startPoint.getZ();double endX = scale.pixelsPerUnit(METER)*endPoint.getX();double endY = scale.pixelsPerUnit(METER)*endPoint.getY();double endZ = scale.pixelsPerUnit(METER)*endPoint.getZ();MarkupSegmentLine segment = new MarkupSegmentLine(startX, startY, startZ, endX, endY, endZ);conveyor.addSegment(segment);}definitionToConveyorMap.put(conveyorDefinition, conveyor);conveyorNetwork.add(conveyor);
}// step4: 自定义站点添加
for(CustomStationDefinition customStationDefinition : layoutDefinition.getCustomStations()){// step4.1: 站点创建CustomStation<Agent> customStation = new CustomStation(customStationDefinition);List<PointDefinition> points = new ArrayList<>();// step4.2: 站点与辊道关联,并绘制站点图形 for(String conveyorCode : customStationDefinition.getInConveyorCodes()){customStation.addConnection(definitionToConveyorMap.get(codeToConveyorDefinitionMap.get(conveyorCode)), PathEndType.END);ConveyorDefinition conveyorDefinition = codeToConveyorDefinitionMap.get(conveyorCode);PointDefinition pointDefinition = codeToPointDefinitionMap.get(conveyorDefinition.getPointCodes().get(conveyorDefinition.getPointCodes().size()-1));points.add(pointDefinition);customStation.addVertex(scale.pixelsPerUnit(METER)*pointDefinition.getX(), scale.pixelsPerUnit(METER)*pointDefinition.getY());}for(String conveyorCode : customStationDefinition.getOutConveyorCodes()){customStation.addConnection(definitionToConveyorMap.get(codeToConveyorDefinitionMap.get(conveyorCode)), PathEndType.BEGIN);ConveyorDefinition conveyorDefinition = codeToConveyorDefinitionMap.get(conveyorCode);PointDefinition pointDefinition = codeToPointDefinitionMap.get(conveyorDefinition.getPointCodes().get(0));points.add(pointDefinition);customStation.addVertex(scale.pixelsPerUnit(METER)*pointDefinition.getX(), scale.pixelsPerUnit(METER)*pointDefinition.getY());}// step4.3: 站点图形补充int conveyorNum = customStationDefinition.getInConveyorCodes().size()+customStationDefinition.getOutConveyorCodes().size();if(conveyorNum==0){error("不允许无连接辊道的ConveyorCustomStation");}else if(conveyorNum==1){// 已有一个点,需要额外补充两个点customStation.addVertex(scale.pixelsPerUnit(METER)*(points.get(points.size()-1).getX()+0.1), scale.pixelsPerUnit(METER)*(points.get(points.size()-1).getY()+0.2));customStation.addVertex(scale.pixelsPerUnit(METER)*(points.get(points.size()-1).getX()+0.1), scale.pixelsPerUnit(METER)*(points.get(points.size()-1).getY()+0.4));}else if(conveyorNum==2){// 已有一个点,需要额外补充一个点,借助两点的法线寻找第三点double x1 = scale.pixelsPerUnit(METER)*points.get(0).getX();double y1 = scale.pixelsPerUnit(METER)*points.get(0).getY();double x2 = scale.pixelsPerUnit(METER)*points.get(points.size()-1).getX();double y2 = scale.pixelsPerUnit(METER)*points.get(points.size()-1).getY();double kAB;  if (x2 - x1 == 0) { kAB = Double.POSITIVE_INFINITY;} else {  kAB = (y2 - y1) / (x2 - x1);  }  double kPerp;  if (kAB == Double.POSITIVE_INFINITY || kAB == Double.NEGATIVE_INFINITY || kAB == 0) {  kPerp = kAB == 0 ? Double.POSITIVE_INFINITY : 0;  } else {  kPerp = -1 / kAB;  }  double xC = x1 + 0.5;  double yC;  if (kPerp == Double.POSITIVE_INFINITY || kPerp == Double.NEGATIVE_INFINITY) {  yC = y1;  } else {  yC = y1 + kPerp * (xC - x1);  }  customStation.addVertex(xC,yC);}conveyorNetwork.add(customStation);
}// step5: 将生成的网络添加到演示中
Level customLevel = new Level(this,"customLevel",SHAPE_DRAW_2D3D,0);
customLevel.add(conveyorNetwork);
customLevel.initialize();
presentation.add(customLevel);

这篇关于【仿真建模-anylogic】动态生成ConveyorCustomStation的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1073699

相关文章

Vue中动态权限到按钮的完整实现方案详解

《Vue中动态权限到按钮的完整实现方案详解》这篇文章主要为大家详细介绍了Vue如何在现有方案的基础上加入对路由的增、删、改、查权限控制,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、数据库设计扩展1.1 修改路由表(routes)1.2 修改角色与路由权限表(role_routes)二、后端接口设计

nginx生成自签名SSL证书配置HTTPS的实现

《nginx生成自签名SSL证书配置HTTPS的实现》本文主要介绍在Nginx中生成自签名SSL证书并配置HTTPS,包括安装Nginx、创建证书、配置证书以及测试访问,具有一定的参考价值,感兴趣的可... 目录一、安装nginx二、创建证书三、配置证书并验证四、测试一、安装nginxnginx必须有"-

Java实战之利用POI生成Excel图表

《Java实战之利用POI生成Excel图表》ApachePOI是Java生态中处理Office文档的核心工具,这篇文章主要为大家详细介绍了如何在Excel中创建折线图,柱状图,饼图等常见图表,需要的... 目录一、环境配置与依赖管理二、数据源准备与工作表构建三、图表生成核心步骤1. 折线图(Line Ch

前端 CSS 动态设置样式::class、:style 等技巧(推荐)

《前端CSS动态设置样式::class、:style等技巧(推荐)》:本文主要介绍了Vue.js中动态绑定类名和内联样式的两种方法:对象语法和数组语法,通过对象语法,可以根据条件动态切换类名或样式;通过数组语法,可以同时绑定多个类名或样式,此外,还可以结合计算属性来生成复杂的类名或样式对象,详细内容请阅读本文,希望能对你有所帮助...

Nginx实现动态封禁IP的步骤指南

《Nginx实现动态封禁IP的步骤指南》在日常的生产环境中,网站可能会遭遇恶意请求、DDoS攻击或其他有害的访问行为,为了应对这些情况,动态封禁IP是一项十分重要的安全策略,本篇博客将介绍如何通过NG... 目录1、简述2、实现方式3、使用 fail2ban 动态封禁3.1 安装 fail2ban3.2 配

Vue3中的动态组件详解

《Vue3中的动态组件详解》本文介绍了Vue3中的动态组件,通过`component:is=动态组件名或组件对象/component`来实现根据条件动态渲染不同的组件,此外,还提到了使用`markRa... 目录vue3动态组件动态组件的基本使用第一种写法第二种写法性能优化解决方法总结Vue3动态组件动态

Android 悬浮窗开发示例((动态权限请求 | 前台服务和通知 | 悬浮窗创建 )

《Android悬浮窗开发示例((动态权限请求|前台服务和通知|悬浮窗创建)》本文介绍了Android悬浮窗的实现效果,包括动态权限请求、前台服务和通知的使用,悬浮窗权限需要动态申请并引导... 目录一、悬浮窗 动态权限请求1、动态请求权限2、悬浮窗权限说明3、检查动态权限4、申请动态权限5、权限设置完毕后

浅析如何使用Swagger生成带权限控制的API文档

《浅析如何使用Swagger生成带权限控制的API文档》当涉及到权限控制时,如何生成既安全又详细的API文档就成了一个关键问题,所以这篇文章小编就来和大家好好聊聊如何用Swagger来生成带有... 目录准备工作配置 Swagger权限控制给 API 加上权限注解查看文档注意事项在咱们的开发工作里,API

Java使用POI-TL和JFreeChart动态生成Word报告

《Java使用POI-TL和JFreeChart动态生成Word报告》本文介绍了使用POI-TL和JFreeChart生成包含动态数据和图表的Word报告的方法,并分享了实际开发中的踩坑经验,通过代码... 目录前言一、需求背景二、方案分析三、 POI-TL + JFreeChart 实现3.1 Maven

Java导出Excel动态表头的示例详解

《Java导出Excel动态表头的示例详解》这篇文章主要为大家详细介绍了Java导出Excel动态表头的相关知识,文中的示例代码简洁易懂,具有一定的借鉴价值,有需要的小伙伴可以了解下... 目录前言一、效果展示二、代码实现1.固定头实体类2.动态头实现3.导出动态头前言本文只记录大致思路以及做法,代码不进