1、模型描述

通过红色飞板,将输送机处的货物逐个传送到货架指定货位,货位由货位表指定。

2、模型布局

3、解决方案

3.1、载荷发生器

首先给载荷发生器创建自定义属性Loc,类型为表。

在载荷发生器的属性窗口中,找到自定义属性Loc,编辑此表,8行*3列,列名分别为rack(货架号)、bay(列号)、lvl(层号),对应货物上架存储的物理位置。每行代表一个载荷,每行值代表每个载荷将来要存放在货架上的位置。

接下来是对载荷生成器生成的每个载荷中,附带货架号、列号、层号信息。方法是在载荷的OnLoadCreated事件中,编写相应代码如下:

function LoadCreator1_OnLoadCreated( sender : Demo3D.Visuals.LoadCreatorVisual, load : Demo3D.Visuals.Visual )
{
    
    var table:Table=sender.Loc.Table;  //定义表,取值为载荷生成器的Loc自定义属性,注意引用表属性时,要额外加 .Table 后缀
    var rowcount:int=table.Rows.Count;  //定义表的总行数
    var seq:int=sender.SequenceNumber;       //定义载荷的生成序号,即载荷生成器创建的第几个载荷

//为当前载荷创建rack、col、lvl 属性,其值为表Loc 的相应列值
    if(!load.HasCustomProperty("rack")){
        load.AddSimpleProperty("rack",table.Rows[seq]["rack"],"rack");
    }
    if(!load.HasCustomProperty("col")){
        load.AddSimpleProperty("col",table.Rows[seq]["col"],"rack");
    }
    if(!load.HasCustomProperty("lvl")){
        load.AddSimpleProperty("lvl",table.Rows[seq]["lvl"],"rack");
    }

//如果当前载荷序号超过了表的总行数,则禁止载荷生成器生成载荷    
    if(seq==rowcount-1){
    sender.ReleaseEnabled=False;
    }
}

在载荷生成器的OnReset事件中启用生成载荷

function LoadCreator1_OnReset( sender : Demo3D.Visuals.LoadCreatorVisual )
{
    sender.ReleaseEnabled=True;
}

3.2、飞板

3.2.1、飞板初始化

在飞板的OnReset事件中编写代码

//自定义移动速度属性

if ( ! sender.HasProperty("LinearSpeed") )
{
        sender.AddSimpleProperty("LinearSpeed", new SpeedProfile(1, 0.5, 0.5),"");
}

//自定义旋转速度属性
if ( ! sender.HasProperty("RotationSpeed") )
{
         sender.AddSimpleProperty("RotationSpeed", new AngularSpeedProfile(90,45, 45), "");
}

sender.WorldLocation = vector(0, 0, 0);         //设置飞板初始位置在世界坐标系原点
sender.WorldRotationY = 0;        //设置飞板的初始旋转轴

3.2.2、设置飞板监听光眼

   

3.2.3、飞板的 OnMessage 事件

编写代码如下:

function flyPad_OnMessage( sender : Demo3D.Visuals.BoxVisual, message : Demo3D.Visuals.ScriptingObject )
{
    //监听到的事件如果不是光眼 PE1的 OnBlocked 事件,则退出本程序,不作任何处理
    if(!(message["MessageType"]=="OnBlocked" && message.MessageSender.Name=="PE1")){
        return;
    }
    
    //否则,进行如下处理
    var load:Visual=message["load"];
    var pe:PhotoEys=message["MessageSender"];
    var conv:Demo3D.Visuals.StraightRollerConveyor= pe.Parent;
    conv.MotorOff();//关闭输送机马达
        
    //飞板原地升降,高度与输送机高度相同
    var targetLoc:Vector3=sender.WorldLocation;
    targetLoc.Y=conv.Height;
    sender.MoveTo(targetLoc,sender.LinearSpeed);
    sender.WaitForMove();
        
    //飞板原地旋转,X轴向与输送机X轴向相对    
    var targetRot:Vector3=Degrees(conv.WorldRotation);
    sender.TurnTo(Axis.Y,180+targetRot.Y,sender.RotationSpeed);
    sender.WaitForMove();
    
    //飞板移动到输送机出口处
    sender.SetInitialPosition();
    var convStartLoc:Vector3=sender.TransformFromWorld(conv.WorldLocation);
    var convEndLoc:Vector3=new Vector3();
    convEndLoc.X=convStartLoc.X-conv.Length-sender.Width/2.0;
    convEndLoc.Z=convStartLoc.Z;
    sender.MoveTo(sender,convEndLoc,sender.LinearSpeed);
    sender.WaitForMove();
    
    //叉齿伸出接货
    var extender:Visual=sender.FindChild("extender");
    extender.TranslateLocalX(load.Width+0.2,1);
    extender.WaitForMove();
    
    //货物绑定到叉齿,叉齿回缩
    load.Stick(extender);
    extender.TranslateLocalX(-load.Width-0.2,1);
    extender.WaitForMove();
    
    var rackIdx:int=load.rack-1;//定义货架排号,取值为货物附带的rack属性值
    var shelfIdx:int=load.lvl-1;//定义货架层号,取值为货物附带的lvl属性值
    var bayIdx:int=load.col-1;//定义货架格号,取值为货物附带的col属性值
    var rack1:Visual=doc.FindVisualByName("Rack1");//货架组件
    var racks:RackVisual[]=rack1.FindType(RackVisual);//定义一个数组,其元素对应为货架组件中的单排货架
    racks.Sort(new VisualDistanceComparer(rack1.WorldLocation));//货架数组排序,即racks[0]为第一排货架,rack[1]为第2排货架,等等
    
    var targetRack:RackVisual=racks[rackIdx];//货物待上架的目标货架
    var shelves:ShelfVisual[]=targetRack.FindType(ShelfVisual);//定义一个数组,其元素为目标货架的各搁板
    shelves.Sort(new VisualDistanceComparer(targetRack.WorldLocation));//搁板数组排序,即shelves[0]为第一层搁板,shelves[1]为第2层搁板,等等
    
    var targetShelf:ShelfVisual=shelves[shelfIdx];//目标搁板
    targetRot=Degrees(targetShelf.WorldRotation);//目标搁板的角度
        
    //奇偶数排货架,其货架前后端位置正好相反    
    if(rackIdx % 2==0){  //奇数排货架
        
        //飞板原地旋转
        sender.TurnTo(Axis.Y,targetRot.Y,sender.RotationSpeed);//飞板原地旋转,角度与目标搁板方向相同
        sender.WaitForMove();
        
        //飞板水平移动到目标搁板前端入口处
        sender.SetInitialPosition();
        targetLoc=targetShelf.WorldLocation;//目标搁板世界坐标
        targetLoc=sender.TransformFromWorld(targetLoc);//将目标搁板世界坐标转换为相对坐标
        //目标位置微调
        targetLoc.X -=sender.Width/2.0;
        targetLoc.Y =0;
        targetLoc.Z -=sender.Depth/2.0;
        //飞板水平移动
        sender.MoveTo(sender,targetLoc,sender.LinearSpeed);
        sender.WaitForMove();
        
        //目标货格位置
        var binLoc:BinLocation=new BinLocation();
        binLoc.Bay=bayIdx;
        binLoc.Bin=0;
        binLoc.Index=0;
        
        //目标货格坐标处理
        sender.SetInitialPosition();
        targetLoc=targetShelf.GetNextStoragePosition(binLoc);//获取目标货格相对目标搁板的的坐标(注意是相对坐标)
        targetLoc=targetShelf.TransformToWorld(targetLoc);//目标位置的相对坐标转换为世界坐标
        targetLoc=sender.TransformFromWorld(targetLoc);//目标位置的世界坐标再转换为相对飞板的相对坐标
        var targetBinLocY:Double=targetLoc.Y;//保存目标货格的Y坐标,用于定位下一步中飞板原地升降的高度
        //目标位置微调
        targetLoc.Y =0;
        targetLoc.Z =0;
        
        //飞板平移动到目标货格附近
        sender.MoveTo(sender,targetLoc,sender.LinearSpeed);
        sender.WaitForMove();
        
        //飞板原地转90°
        sender.SetInitialPosition();
        sender.TurnTo(sender,Axis.Y,270,sender.RotationSpeed);
        sender.WaitForMove();
        
        //飞板原地升降到目标货格高度
        sender.SetInitialPosition();
        targetLoc.X=0;
        targetLoc.Y=targetBinLocY;
        targetLoc.Z=0;
        sender.SetInitialPosition();
        sender.MoveTo(sender,targetLoc,sender.LinearSpeed);
        sender.WaitForMove();
        
        
        //叉齿伸出放货
        sender.SetInitialPosition();
        extender.TranslateLocalX(load.Width+targetShelf.BayDepth/2.0,1);
        extender.WaitForMove();
        
        //放货,将货物与目标搁板绑定
        load.Stick(targetShelf);
        //叉齿缩回
        sender.SetInitialPosition();
        extender.TranslateLocalX(-(load.Width+targetShelf.BayDepth/2.0),1);
        extender.WaitForMove();
        
        //飞板移动到目标搁板入口处
        sender.SetInitialPosition();
        targetLoc=targetShelf.WorldLocation;
        targetLoc=sender.TransformFromWorld(targetLoc);
        targetLoc.X -=sender.Width/2.0;
        targetLoc.Z +=sender.Depth/2.0;
        sender.MoveTo(sender,targetLoc,sender.LinearSpeed);
        sender.WaitForMove();

}    
    else{        //偶数排货架
        //飞板原地旋转
        sender.TurnTo(Axis.Y,180+targetRot.Y,sender.RotationSpeed);//飞板原地旋转,角度与目标搁板方向相同
        sender.WaitForMove();
        
        //飞板水平移动到目标搁板后端入口处
        sender.SetInitialPosition();
        targetLoc=targetShelf.WorldLocation;//目标搁板世界坐标
        targetLoc=sender.TransformFromWorld(targetLoc);//将目标搁板世界坐标转换为相对坐标
        //目标位置微调
        targetLoc.X -=(targetShelf.OverallLength+sender.Width/2.0);
        targetLoc.Y =0;
        targetLoc.Z +=sender.Depth/2.0;
        //飞板水平移动
        sender.MoveTo(sender,targetLoc,sender.LinearSpeed);
        sender.WaitForMove();
        
        //目标货格位置
        var binLoc:BinLocation=new BinLocation();
        binLoc.Bay=bayIdx;
        binLoc.Bin=0;
        binLoc.Index=0;
        
        //目标货格坐标处理
        sender.SetInitialPosition();
        targetLoc=targetShelf.GetNextStoragePosition(binLoc);//获取目标货格相对目标搁板的的坐标(注意是相对坐标)
        targetLoc=targetShelf.TransformToWorld(targetLoc);//目标位置的相对坐标转换为世界坐标
        targetLoc=sender.TransformFromWorld(targetLoc);//目标位置的世界坐标再转换为相对飞板的相对坐标
        var targetBinLocY:Double=targetLoc.Y;//保存目标货格的Y坐标,用于定位下一步中飞板原地升降的高度
        //目标位置微调
        targetLoc.Y =0;
        targetLoc.Z =0;
        
        //飞板平移动到目标货格附近
        sender.MoveTo(sender,targetLoc,sender.LinearSpeed);
        sender.WaitForMove();
        
        //飞板原地转90°
        sender.SetInitialPosition();
        sender.TurnTo(sender,Axis.Y,90,sender.RotationSpeed);
        sender.WaitForMove();
        
        //飞板原地升降到目标货格高度
        sender.SetInitialPosition();
        targetLoc.X=0;
        targetLoc.Y=targetBinLocY;
        targetLoc.Z=0;
        sender.SetInitialPosition();
        sender.MoveTo(sender,targetLoc,sender.LinearSpeed);
        sender.WaitForMove();
        
        
        //叉齿伸出放货
        sender.SetInitialPosition();
        extender.TranslateLocalX(load.Width+targetShelf.BayDepth/2.0,1);
        extender.WaitForMove();
        
        //放货,将货物与目标搁板绑定
        load.Stick(targetShelf);
        //叉齿缩回
        sender.SetInitialPosition();
        extender.TranslateLocalX(-(load.Width+targetShelf.BayDepth/2.0),1);
        extender.WaitForMove();
        
        //飞板水平移动到目标搁板后端入口处
        sender.SetInitialPosition();
        targetLoc=targetShelf.WorldLocation;//目标搁板世界坐标
        targetLoc=sender.TransformFromWorld(targetLoc);//将目标搁板世界坐标转换为相对坐标
        //目标位置微调
        targetLoc.X -=sender.Depth/2.0;
        targetLoc.Z -=(targetShelf.OverallLength+sender.Width/2.0);
        //飞板水平移动
        sender.MoveTo(sender,targetLoc,sender.LinearSpeed);
        sender.WaitForMove();    
    
    }
    conv.MotorOn();//飞板完成传输任务后,开启输送机马达,使得输送机上的下一个载荷移动,又一次触发光眼的 OnBlocked 事件。

}

4、最终效果

5、学习小结

5.1、利用载荷发生器的SequenceNumber属性,作为行号去读取一个表的行列值;

5.2、用代码对载荷发生器创建的载荷,创建待上架位置的自定义属性;

5.3、用代码开启某对象的监听功能,设置两个对象之间监听和被监听的关系;

5.4、对象的 OnMessage 事件,以及参数message的运用,注意参数 message 的数据类型是字典,其主要键名有MessageSender、MessageType;

5.5、利用飞板的 OnMessage 事件,来处理飞板监听到的光眼封堵事件;

5.6、对象移动函数 MoveTo()、旋转函数 TurnTo() 的应用,特别要注意参考坐标系的应用;

5.7、对象旋转时,应注意单位是角度还是弧度,以及角度单位的转换;

5.8、参考坐标系为相对坐标时,SetInitialPosition() 函数的应用;

5.9、注意货架组中,奇数排货架和偶数排货架的前端/后端位置正好相反;

5.10、获取货架的货格位置的相应坐标函数 Shelf.GetNextStoragePosition(binLoc) 的应用;

5.11、货架对象的层级关系:货架对象 > 货架组 RackVisual[ ]> 搁板组  ShelfVisual[ ]> 货格组;

5.12、Sort()函数对货架数组 RackVisual[ ]、搁板数组  ShelfVisual[ ] 中的元素按某种规则进行排序。

(Demo3D 学习笔记)案例2:飞板传输货物,并按指定货位上架相关推荐

  1. 献给入门小白的MySQL学习笔记+案例

    MySQL学习笔记 目录 MySQL学习笔记 1.SQL概述 1.1:数据库的好处 1.2:数据库管理系统 1.3:SQL语言概述 1.4:SQL语言的分类 2.安装与使用 2.1:MySql数据库产 ...

  2. CSS入门学习笔记+案例(1)

    CSS入门学习 一.CSS简介 1.什么是CSS CSS:Cascading Style Sheet 层叠样式表 是一组样式设置的规则,用于控制页面的外观样式 2.为什么使用CSS 实现内容与样式的分 ...

  3. [学习笔记] BearPi-HM Nano - 开发板介绍

    声明:         1. 该系列学习笔记整理自BearPi社区以及网络资源 2. 阅读本系列笔记需要部分单片机.电子技术和C语言基础 3. 才疏学浅,若有谬误,敬请指正 目录 前言 一.Harmo ...

  4. OpenFOAM学习笔记 案例1之Cavity(1)

    OpenFOAM照比商业软件如Fluent Star-CCM 较难,是因为其操作需要较高的编程能力.而我不具备这种能力,只能通过一个一个的案例来学习,也希望对其他OpenFOAM新手提供一些帮助. 在 ...

  5. HTML入门学习笔记+案例(1)

    一.HTML简介 1.HTML是什么? HTML:hyper text markup language超文本标记(标签)语言由各种标签组成,用来制作网页,告诉浏览器该如何显示页面 2.作用 制作网页, ...

  6. HTML入门学习笔记+案例

    一.HTML简介 1.HTML是什么? HTML:hyper text markup language超文本标记(标签)语言由各种标签组成,用来制作网页,告诉浏览器该如何显示页面 2.作用 制作网页, ...

  7. java文件传输连接方式_Java 学习笔记 网络编程 使用Socket传输文件 CS模式

    Socket的简单认识 Socket是一种面向连接的通信协议,Socket应用程序是一种C/S(Client端/Server端)结构的应用程序 Socket是两台机器间通信的端点. Socket是连接 ...

  8. [游戏开发-学习笔记]菜鸟慢慢飞(12)- Unity3D中LitJson 解析遇到的问题

    1.数据格式问题 问题:服务器那边设置的HP的类型是float,如果传给客户端的是1000,没有小数点解析的时候LitJson会优先按照int去解析.但是呢,服务器回头还有可能传回的是1000.50这 ...

  9. [游戏开发-学习笔记]菜鸟慢慢飞(14)- ScrollView刷新

    /// <summary>/// 刷新,解决scroll view排序不对的问题 /// </summary>/// <returns>The scroll vie ...

  10. python空气质量指数计算_Python的学习笔记案例8--空气质量指数计算5.0

    之前都是使用提前准备好的文件来获取数据,时效性很差. 为了更有效.更快地获取并利用网络信息并工作提高效率,出现了网络爬虫. 利用网络爬虫实时获取城市的空气质量指数. 什么是网络爬虫? 自动抓取互联网信 ...

最新文章

  1. objdump与readelf
  2. 对象存储与块存储、文件存储等对比
  3. lolfps高但画面不流畅_你吃鸡卡吗,超详细和平精英画面设置教程,解决卡顿,主播都在用...
  4. cd mysql 权限不够_.bash_profile权限不够_cdmysql权限不够
  5. 代码审查“思维导图”
  6. Python2.7升级至Python3.6
  7. 联想智能云教室安win7_联想智能云教室解决方案-联想商用.PDF
  8. 阿里云储存OSS(服务端签名后前端直传)
  9. 用matlab模拟等离子体论文,等离子体模型的建立
  10. 现在学 Prolog 递归
  11. 无法找到c语言dll入口点,c# – 无法在DLL中找到入口点
  12. 403错误服务器未响应是什么意思,什么是HTTP ERROR 403?导致403错误的主要原因及解决方法...
  13. 《计算机工程》投稿经验分享
  14. 过滤汉字和特殊字符的正则表达式
  15. JS的onload事件
  16. windows客户端通过脚本文件添加信任站点
  17. 解决“8080端口“被占用问题
  18. 2023最新支付宝微信运动步数网页源码+附带原始接口
  19. Java栈的实现数组和链表
  20. 字符串的输入输出处理

热门文章

  1. 新手入门C语言易错点
  2. PS4蓝牙手柄分析之1
  3. Android Studio配置ADB环境变量
  4. python 写入文件时编码问题
  5. VGS--网络三维互动软件技术
  6. java下载服务器资源
  7. .NET/C#大型项目研发必备(12)--使用MQ消息队列
  8. Hadoop KMS 使用
  9. windows putty Bitvise 登陆linux 服务器
  10. 极客时间-技术领导力300讲-小小读后感