YRC1000 新语言环境 MotoPlus 程序员手册(1)

发布时间:2020-10-02 | 杂志分类:其他
免费制作
更多内容

YRC1000 新语言环境 MotoPlus 程序员手册(1)

HW1483597-C 10 传感器控制服务 10.5 传感器控制 API 清单 10.5 传感器控制 API 清单 MotoPlus 功能 1 mpReceiveSkillCommand 从系统接收 SKILLSND 发送的传感器指令 2 mpEndSkillCommandProcess 向系统发出指令接收时执行的一系列处理的 结束通知。通过这样,程序执行SKILLSND 的下一个命令。 3 mpMeiGetJobExecTask 获取执... [收起]
[展开]
YRC1000 新语言环境 MotoPlus 程序员手册(1)
粉丝: {{bookData.followerCount}}
文本内容
第51页

HW1483597-C 10 传感器控制服务 10.5 传感器控制 API 清单 10.5 传感器控制 API 清单 MotoPlus 功能 1 mpReceiveSkillCommand 从系统接收 SKILLSND 发送的传感器指令 2 mpEndSkillCommandProcess 向系统发出指令接收时执行的一系列处理的 结束通知。通过这样,程序执行SKILLSND 的下一个命令。 3 mpMeiGetJobExecTask 获取执行中的程序的系列(任务)编号 4 mpMeiGetExecControlGroup 获取执行中的移动命令(插补处理中命令) 的路径的控制组 5 mpMeiGetInterpolation 获取执行中程序的移动命令的插补类别 6 mpMeiPutCorrPath 给插补处理中路径设定轨迹修正量 7 mpMeiPutForcePathEnd 强制结束执行中的移动命令 8 mpMeiPutSpdOverride 设定执行中的移动命令的速度倍率 9 mpMeiIncrementMove 给正在执行 WAIT 命令的机器人按插补周期 设定增量移动量。 10-10 HW1483597-C

第52页

HW1483597-C 11 机器人运行控制服务 11.1 增量值移动功能 11 机器人运行控制服务 机器人运行控制服务提供运行机器人的 API 群。 11.1 增量值移动功能 增量值移动功能由 mpExRcsIncrementMove() 提供,机器人在 WAIT 命令执 行中执行此 API,进行指定量的增量值移动。 例如,用此 API 向 y 方向指定 0.1mm 的增量值后,如果插补周期为 4msec,将在 2 秒内进行 500 次的增量值移动,机器人向 y 方向运行 50.0mm。 㻌㻌㻌㻌ਸ䇑Ⲵ໎䟿 㼅 㻡㻜㼙㼙 䠎。 ᰦ䰤 11.2 机器人运行控制 API 清单 MotoPlus 功能 1  mpExRcsIncrementMove   给正在执行 WAIT 命令的机器人按插补周 期设定增量移动量。 11-1 HW1483597-C

第53页

HW1483597-C 12 伺服控制服务 12.1 功能概要 12 伺服控制服务 通过利用伺服控制服务,可以从 MotoPlus 实时获取电机的速度和扭矩的数 据,以及直接控制电机的扭矩。 要使用伺服控制服务需要另外的选装 MotoFit 功能。 注意 • 由于使用伺服控制服务,而不能保持电机的位置,可能导致电机向 意想不到的方向运行。 请在充分确认安全性的基础上使用此服务。 • 利用伺服控制服务的 MotoPlus 应用意外停机时,电机可能会接收意 想不到的扭矩指令,从而导致陷入危险状态。 在利用伺服控制服务的时候,请务必与用户看门狗服务一起使用, 如果应用意外停机时,请采取对策,例如结束伺服控制服务等。 12.1 功能概要 伺服控制服务主要提供下表所示的功能。 功能 概要 反馈速度/扭矩获取功能 扭矩限制功能 实时获取现在的反馈速度和扭矩。 扭矩控制功能 限制电机的扭矩。 但是对象仅为外部轴。 直接控制电机的扭矩。 但是对象仅为外部轴。 伺服控制服务处理的扭矩的方向 ( 符号)与轴的旋转方向相 同。并且,与速度的方向一致。 但是,有时会与系统监视用的 API mpGetTorque() 获取的扭矩 方向不同。 mpGetTorque() 中,电机的正转方向不是轴的旋转方向,是扭 矩的正方向。有时轴的正转方向与电机的正转方向相反。此 时, mpGetTorque() 获取的扭矩与速度及伺服控制 API 处理的 扭矩朝向相反。 12-1 HW1483597-C

第54页

HW1483597-C 12 伺服控制服务 12.1 功能概要 12.1.1 反馈速度 / 扭矩获取功能 可以通过 mpSvsGetVelTrqFb() 获取所有控制组 / 所有轴的反馈速度与扭 矩。 而且,返回反馈速度与扭矩的 API 其他还有,系统监视用的 API mpGetFBSpeed(), mpGetTorque(),但是伺服控制服务用的 API mpSvsGetVelTrqFb() 中通过 I/O 控制周期更新数据,可以更实时地获取速 度与扭矩。 12.1.2 扭矩限制功能 / 扭矩控制功能 扭矩限制与扭矩控制按同样的步骤使用。 首先,如下面流程图所示,执行扭矩限制 / 扭矩控制的开始 API mpSvsStartTrqLimit() / mpSvsStartTrqCtrl()。此时,指定执行扭矩限制 / 扭 矩控制的对象组与轴。能指定的仅外部轴。 其次,用扭矩限制值 / 扭矩指令值的设定 API mpSvsSetTrqLimit() / mpSvsSetTrqCtrl() 设定扭矩限制值 / 扭矩指令值。执行开始 API 后,在首 次执行设定 API 时开始执行实际的扭矩限制 / 扭矩控制。 设定 API 可以以任意的间隔执行。一旦设定了的扭矩限制值 / 扭矩指令值 被保持到执行下一个设定 API 为止。 结束扭矩限制 / 扭矩控制时,执行扭矩限制 / 扭矩控制的结束 API mpSvsEndTrqLimit() / mpSvsEndTrqCtrl()。 并且,即使是设定 API 向对象组输出移动命令时(即使是运行中)也可以 执行,但是开始 API 和结束 API 只能在没有向对象组输出移动命令 (不是 运行中)的时候可以执行。 关于开始、设定、结束的各个 API 的详细,请参照「YRC1000 新语言环境 MotoPlus 参考手册功能扩展版(HW1483601)」。 开始扭矩限制/扭矩控制。 (执行 㔗㔝进行扭矩限制吗? 设定扭矩限制值/扭矩指令值。 (执行 结束扭矩限制/扭矩控制。 (执行 12-2 HW1483597-C

第55页

HW1483597-C 12 伺服控制服务 12.2 使用例 注意 • 在执行扭矩限制 / 扭矩控制的时候,因电机的位置不受控制,可能 会向意想不到的方向运行。因此,请在执行扭矩限制 / 扭矩控制的 时候,定期监视 FB 位置,如果 FB 位置超出规定的范围,请结束扭 矩限制 / 控制。 • 如果给重力等作用的轴设定扭矩限制值 / 扭矩指令值为 \"0\",轴将向 重力等作用的方向运行。 而且,给扭矩指令值输入过大的值后,有可能轴会运行。 开始扭矩限制 / 扭矩控制之前,通过 mpSvsGetVelTrqFb() 确认当 前的扭矩,确认完扭矩限制值 / 扭矩指令值的设定值是否适当之后, 请设定扭矩限制值 / 扭矩指令值。 扭矩限制及扭矩控制不会因为关闭伺服电源和发生报警而在 系统端自动结束。(伺服被关闭,再次打开伺服时继续执行扭 矩限制 / 扭矩控制。) 在关闭伺服和发生报警时,如果结束扭矩限制和扭矩控制, 请监视伺服电源和报警的状态,根据需要执行 mpSvsEndTrqLimit() / mpSvsEndTrqCtrl()。 12.2 使用例 12.2.1 工件位置检测 运行 在用 mpSvsGetVelTrqFb() 监视扭矩值的同时,让外部轴向工件运行。然 后,当扭矩值变成一定值以上的时候,用 mpGetFBPulsePos() 获取 FB 位 置,将此位置定为工件位置。 并且,伺服控制服务对外部轴进行扭矩限制。之后用 mpSvsGetVelTrqFb() 监视速度的同时,让外部轴向工件运行。当速度变成一定值以上的时候, 用 mpGetFBPulsePos() 获取 FB 位置,将此位置定为工件位置。 12-3 HW1483597-C

第56页

HW1483597-C 12 伺服控制服务 12.3 伺服控制 API 清单 12.2.2 未知尺寸工件的夹持 运行 用 mpSvsGetVelTrqFb() 监视扭矩值的同时,让外部轴向工件运行。然后, 当扭矩值变成一定值之后,执行伺服控制服务的扭矩控制,用规定的力夹 持工件。 12.3 伺服控制 API 清单 MotoPlus 功能 1 mpSvsGetVelTrqFb 获取当前的反馈速度与扭矩 2 mpSvsStartTrqLimit 扭矩限制的开始 3 mpSvsSetTrqLimit 扭矩限制值的设定 4 mpSvsEndTrqLimit 扭矩限制的结束 5 mpSvsStartTrqCtrl 扭矩控制的开始 6 mpSvsSetTrqCtrl 扭矩指令值的设定 7 mpSvsEndTrqCtrl 扭矩控制的结束 8 mpSvsForceInit 伺服控制的强制结束 12-4 HW1483597-C

第57页

HW1483597-C 13 内存管理大小 13.1 内存管理 API 清单 13 内存管理大小 此服务为不影响系统,在 MotoPlus 用的管理区域进行 malloc、mfree。 MotoPlus 不能使用标准函数 malloc、mfree,请使用此 API。 用 mpMalloc 确保的区域请务必用 mpFree 进行释放。 13.1 内存管理 API 清单 功能 内存的确保 MotoPlus 内存的释放 1 mpMalloc 2 mpFree 13-1 HW1483597-C

第58页

HW1483597-C 14 通用文件控制大小 14.1 有关文件的命名、大小的规约 14 通用文件控制大小 用户能在控制柜的CMOS 上配置的SRAM 驱动、DRAM 驱动、或 CPU基 板(JANCD-ACP01)正面的USB 驱动上自由进行文件的生成、读写、删 除的大小。 SRAM 驱动、USB 驱动生成的文件即使关闭电源也会继续保 留,但是 DRAM 驱动生成的文件会因关闭电源而被删除。 要使用 SRAM 驱动,需要机器人 I/F 基板的内存扩展选装(JANCD-AIF01- 2E)。 14.1 有关文件的命名、大小的规约 关于 MotoPlus 的通用文件的命名规约列举如下。 (1) 指定文件名的时候,必须指定包含驱动器号的完整路径名。 (2) 驱动端口号定义如下, SRAM 驱动 MP_SRAM_DEV_DOS (「MPSRAM1:0」) DRAM 驱动 MP_DRAM_DEV_DOS (「MPRAM1:0」) USB 驱动 0 MP_USB0_DEV_DOS (「MPUSB0」) USB 驱动 1 MP_USB1_DEV_DOS (「MPUSB1」) 。 < USB 驱动的指定方法> 摘录 CPU 基板(JANCD-ACP01)CN106 部分 ᐖ‫ח‬86%䘎᧕ಘ 03B86% B'(9B'26 ͆0386% ͇ ਣ‫ח‬86%䘎᧕ಘ 03B86% B'(9B'26 ͆0386% ͇ (3) 路径名接在驱动端口号后面使用表示根目录的「¥」或「/」。 (4) 除去驱动端口号和路径名的文件名和目录名单个的拼写的最大 长度是 32 个字符。 (5) 文件名和目录名中不能使用全角字符。 (6) 创建文件和目录时,输入的名称的大写字符和小写字符都将如 实反映出来。 变更名称的时候,关于变更后的名称也同样。 (7) 使用与既存的文件与目录的名称的仅大小写字符不同的名称, 不能新创建文件与目录,以及进行名称变更。 (8) 在文件与目录的创建 / 名称变更之外的情况,指定名称的时候, 拼写的大写字符、小写字符一样。 (6)(7)(8) 的示例 mpCreate(\"MPUSB0/AbCd.txt\"); ⇒ AbCd.txt 被创建。 (输入的大写字符、小写字符将如实反映 ) mpCreate(\"MPUSB0/ABCD.TXT\"); ⇒ ABCD.TXT 不被创建。 (因为 AbCd.txt 已经存在了) 14-1 HW1483597-C

第59页

HW1483597-C 14 通用文件控制大小 14.1 有关文件的命名、大小的规约 mpRemove(\"MPUSB0/ABCD.TXT\"); ⇒ AbCd.txt 将被删除。(大写 字符、小写字符与文件名称不一致也将被删除) (9) 路径名的最大长度是包含驱动号255 个字符。 (10) 驱动的容量, SRAM、DRAM 都是 512 KB。 • 不创建从多个任务执行文件的读(mpRead)写(mpWrite) 的应用,文件的读写请用1个任务执行。 在执行多个任务的读写时,如果切断控制柜的电源,可能会 导致 CMOS内存上的文件陷入意外状态。 • CMOS上的用户定义文件所需的东西请保存至外部存储。 万一CMOS内存上的文件系统破损,在维护模式下对用户定 义文件进行初始化,可以通过从外部存储介质加载已经保存 的文件来修复。 • 文件的读(mpRead)写(mpWrite)使用执行了 API 的 MotoP- lus 任务的堆栈。因此,用文件的读写指定的数据大小,含 MotoPlus 任务的执行代码、变量大小等,请不要超过最大堆 栈大小(40Kbyte)。 如果指定了超过 MotoPlus 任务的最大堆栈大小(40Kbyte)的 数据大小, YRC1000或MotoPlus应用将不能正常运行。 (关于现象,请参照「16.8 “ 调试时的现象与设想的编码上 的问题 /调查方法 ”」。) 例)mpRead(fd, buffer, 60*1024); :数据大小 60Kbyte                (超出堆栈大小) 此时, mpRead(fd, buffer, 30*1024); mpRead(fd, buffer, 30*1024); 。 14-2 HW1483597-C

第60页

HW1483597-C 14 通用文件控制大小 14.2 有关 USB 连接器及 USB 存储器的规约 14.2 有关 USB 连接器及 USB 存储器的规约 有关 CPU 基板 (JANCD-ACP01) 的 USB 连接器及安装的 USB 存储器的规 约列举如下。 1. 控制电源 ON 时禁止插拔 USB 存储器 插入 USB 存储器时会执行设备的识别处理,因此可能会对机器人 的运行(循环时间)带来影响。 控制电源 ON 时请不要插拔 USB 存储器。 2. 禁止访问中切断电源以及插拔 USB 存储器 FAT 可能已经损坏,请不要在访问中切断电源以及插拔 USB 存储 器。 3. 用户定义文件不对应 不能通过外部存储功能的 [ 文件 ] → [ 初始化 ] → [ 用户定义文件 ] 进行存储器的文件操作(加载、保存、初始化)。 4. 对 USB 存储器的访问速度 对 USB 存储器的访问速度比 SRAM 驱动低,之前 API 执行对 SRAM 驱动的访问指定,如果变更为对 USB 存储器的访问指定, 请确定与其他处理是否取得同步。 5. USB 存储器运行温度范围 请在 YRC1000 的柜内温度范围内使用 USB 存储器。 6. 控制柜振动导致 USB 存储器松脱 请防止因控制柜的振动而造成 USB 存储器脱落。 (对策示例) ・工装固定以防 USB 存储器松脱等。 7. CPU 基板(JANCD-ACP01)前面的 USB 连接器 CPU 基板(JANCD-ACP01)前面的 USB 连接器只能使用 USB 存 储器。 请不要连接 USB 集线器和其他 USB 设备。 8. USB 存储器的容量 请使用 4Gbyte 以下的 USB 存储器。 14-3 HW1483597-C

第61页

HW1483597-C 14 通用文件控制大小 14.3 打开文件时的访问权 14.3 打开文件时的访问权 文件控制 API 在文件生成 / 打开时可以设定以下的访问权。 访问权 值 说明 O_RDONLY 0 读取专用 O_WRONLY 1 O_RDWR 2 编辑专用 O_CREAT 0x0200 可读写 创建并打开文件 (mpOpen 时,请与其他 3 个访问权的逻 辑和结合使用。) 这些设定在文件生成(mpCreate)或打开(mpOpen)时按分配的文件描述 符(fd)单个设定。 在打开文件的时候(mpClose 时)fd 变为无效,访问权也消失。 14.4 可以使用的任务优先级 文件控制 API 能使用的任务优先级为常规优先级 (MP_PRI_TIME_NORMAL)。 从更高优先级的任务读取时,根据参数 S2C1101 的设定,如下表所示运行 有异。 并且,此设定在维护模式的「FileControl 服务任务优先级限制」也可变更。 S2C1101 的值 FileControl 服务任务优先级 处理 限制 0 API 返回错误 1(初始值) 限制 将任务优先级暂时降至 MP_PRI_TIME_NORMAL 执 自动调整 行 关于「FileControl 服务任务优先级限制」的变更方法,请参照「YRC1000 新语言环境 MotoPlus 用户手册 (HW1483599)」的「5.3 章 FileControl 服务 任务优先级限制的设定」。 14-4 HW1483597-C

第62页

HW1483597-C 14 通用文件控制大小 14.5 通用文件控制 API 清单 14.5 通用文件控制 API 清单 MotoPlus 功能 1 mpCreate 2 mpOpen 生成新文件 3 mpRemove 打开文件 4 mpClose 生成文件 5 mpRename 关闭文件 6 mpRead 变更文件名 7 mpWrite 从文件读取数据 8 mpIoctl 将数据写入文件 9 mpLseek 控制设备 10 mpFstat 移动文件指针 获取文件的状态信息 11 mpStat (fd 指定) 获取文件的状态信息 12 mpOpendir (文件名指定) 13 mpReaddir 打开目录 14 mpRewinddir 从打开的目录读一个条目 15 mpClosedir 将目录描述符进行复位 16 mpCreatedir 关闭目录 生成新的目录 17 mpRemovedir ( 仅 USB 驱动指定时能使用) 删除目录 18 mpRenamedir ( 仅 USB 驱动指定时能使用) 变更目录名 ( 仅 USB 驱动指定时能使用) 14-5 HW1483597-C

第63页

HW1483597-C 15 既存系统文件控制服务 15.1 既存系统文件控制 API 清单 15 既存系统文件控制服务 访问程序和各种设定文件类,读取至 RAM 驱动、或 USB 驱动,以文本形 式输出。并且,可以将 RAM 驱动、USB 驱动上的文件写入系统。 要使用 SRAM 驱动,需要机器人 I/F 基板的内存扩展选装(JANCD-AIF01- 2E)。 MotoPlus 的文件系统中不能使用全角字符,因此不能访问含 全角字符的程序等。 关于文件的名称等的规约请参照「14.1 “ 有关文件的命名、 大小的规约 ”」。 关于访问 RAM 驱动上的文件,请参照「14 “ 通用文件控制大小 ”」。 15.1 既存系统文件控制 API 清单 MotoPlus 功能 1 mpLoadFile 将 RAM 驱动、或 USB 驱动的文件写入 2 mpSaveFile 控制柜 将控制柜的文件读入 RAM 驱动、 USB 3 mpRefreshFileList 驱动 4 mpGetFileCount 更新文件清单 5 mpGetFileName 获取文件清单的文件数 6 mpFdWriteFile 从文件清单获取文件名 7 mpFdReadFile 指定 fd,将文件写入控制柜 8 mpFdGetJobList 指定 fd,从控制柜读取文件 获取程序一览 进行既存文件的加载、 保存,调用 mpLoadFile、mpSaveFile、 mpFdWriteFile、mpFdReadFile 后,为防止发生系统内部信息 的矛盾,变成禁止编辑状态。因此,程序的编辑状态、变量 和 I/O 的编辑状态将被初始化,示教器将暂时不能操作。因 此,为防止阻碍从示教器进行编辑操作,在示教模式使用这 些 API 时,请只在必要的情况下使用,不继续执行加载和保 存。 15-1 HW1483597-C

第64页

HW1483597-C 16 编程 16.1 规则 16 编程 16.1 规则 16.2 创建源程序时的规则如下所示。 文件名:最大半角 32 个字符。可使用全角字符。可识别大写字符/小写字 符。后缀为「.c」。 C 编码规则 遵守标准的 ANSI - C 的编码规则。 16.3 程序的执行 16.4 应用程序在接通电源时自动加载 \"xxxxxx.out\" 文件,将其中的 mpUsrRoot() 函数视为任务自动启动。 应用程序必须需要唯一 mpUsrRoot()。 mpUsrRoot() 的最后记述 mpExitUsrRoot;。这是一个终止 mpUsrRoot 的任务的宏。 MotoPlus 编码规则 1. 程序开头必须包含 MotoPlus.h。此包含文件中含有所有的提供的服 务的标题信息。 2. 应用的入口函数为 void mpUsrRoot (int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7, int arg8, int arg9, int arg10),返回值不 指定,最后请记述 mpExitUsrRoot;。 int mpUsrRoot (int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7, int arg8, int arg9, int arg10) { /* argc 表示函数的量。 ・ ・ mpExitUsrRoot; // 请务必记述后结束 } mpUsrRoot 的任务以启动其他的应用任务并且快速进行应用整 体的初始化为目的,具有较高的任务优先级。由于任务优先 级较高,如果在此任务中进行长时间(100μsec 以上)处理, 可能会因机器人控制的处理时间不足而导致系统发生报警、 示教器不能操作、不能进行暂停操作等。因此,像样本程序 「17.3 “ 任务控制样本程序 ”」一样,在启动其他的任务和生成 信号量之后,请务必结束 mpUsrRoot 的任务。 16-1 HW1483597-C

第65页

HW1483597-C 16 编程 16.5 编程时的限制事项 3. 记述源代码时的注意 在记述注释时,如果使用 \"//\",请注意不要将以下的字符作为注释 使用。编译器判断为异常,将不能正常进行编译。 <编译器错误识别的字符> ソ,噂,圭,構,十,申,貼,能,表,暴,予 *这些字符的第 2Byte 为 '¥'(0x5C)的字符,这里的 0X5C 如果 在第 2Byte,将不能正常处理注释。 16.5 编程时的限制事项 16.5.1 能使用的 ANSI-C 的标准函数 ANSI-C 的标准函数中能使用的函数如下所示。不支持其他函数。 不支持 的主要函数是内存分配函数、文件控制函数的 Open、close。系统分配可能 导致内存泄漏从而发生系统故障,以及如果用标准函数获取较大的内存, 系统可能发生故障。 有关文件,主 CPU 的 SD 文件为了防止关闭电源时破 坏文件,使用了特殊的访问方法,因为不能进行标准的 OPEN、CLOSE。 并且,等待输入(getc, getchar, gets)的函数因为任务停止而不能使用。 • ctype.h 文字操作 isalnum isalpha iscntrl isdigit isgraph islower isprint ispunct isspace isupper isxdigit tolower toupper • locale.h 语言环境设定特性操作 localeconv setlocale • math.h 数学 acos asin atan atan2 ceil cos cosh exp floor fabs fmod frexp ldexp log log10 modf pow sin sinh sqrt tan tanh • stdarg.h 可变实数 va_arg va_end va_start • stdio.h 输入输出 printf putc putchar puts sprintf vfprintf vprintf vsprintf • stdlib.h 通用工具 abs atof atoi atol bsearch div exit getenv labs ldiv qsort rand srand strtod strtol strtoul system • string.h 字符串操作 memchr memcmp memcpy memmove memset strcat strchr strcmp strcoll strcpy strcspn strerror strlen strncat strncmp strncpy strpbrk strrchr strspn strstr strtok strxfrm 16-2 HW1483597-C

第66页

HW1483597-C 16 编程 16.6 编程时的注意事项 16.5.2 任务的优先级和能使用的 API 根据任务的优先级,对能使用的 API 有限制。以下表示优先级和能使用的 API。由于下述以外的 API的处理时间较长,请不要使用高优先级的任务。 优先级 能使用的 API I/O 控制周期通知 mpReadIO, mpWriteIO, mpGetUserVars, 任务用 mpPutUserVars, mpMsgQSend, mpErrMsgQSnd, mpSemGive, mpTaskDelay, 插补周期通知 mpGetRtc, mpClkAnnounce, 任务用 mpStopWatchCreate, mpStopWatchDelete, mpStopWatchStart, mpStopWatchStop, mpStopWatchLap, mpStopWatchReset,mpStopWatchGetTime, mpStopWatchGetLapNum, mpStopWatchGetLapTime, mpStopWatchGetAliveLapNo, mpUsrWdogStart, mpUsrWdogClear, mpSvsGetVelTrqFb, mpSvsSetTrqLimit, mpSvsSetTrqCtrl, mpCtrlGrpId2GrpNo 上述 API(I/O 控制周期通知任务能使用的 API) ,mpMeiGetJobExecTask, mpMeiGetInterpolation, mpMeiGetExecControlGroup, mpMeiPutCorrPath, mpMeiPutForcePathEnd, mpMeiPutSpdOverride, mpMeiIncrementMove, mpExRcsIncrementMove 高优先级 上述 API(插补周期通知任务能使用的 API), mpGetVarData, mpGetSVarData, mpGetPosVarData, mpPutVarData, mpPutSVarData, mpPutPosVarData, mpSocket, mpListen, mpAccept, mpBind, mpConnect, mpRecv, mpRecvfrom, mpSend, mpSendto, mpClose, mpHtonl, mpHtons, mpNtohl, mpNtohs, mpInetAddr, mpInetNtoa, mpInetNtoaB, mpGetsockname, mpGetpeername, mpSetsockopt, mpIoctl, mpSelect, mpRsOpen, mpRsClose, mpRsSend, mpRsRecv, mpConvAxesToCartPos, mpConvCartPosToAxes, mpConvPulseToAngle, mpConvAngleToPulse, mpConvFBPulseToPulse, mpMakeFrame, mpInvFrame, mpRotFrame, mpMulFrame, mpZYXeulerToFrame, mpFrameToZYXeuler, mpCrossProduct, mpInnerProduct 16.6 编程时的注意事项 C 语言编程可以使用存储有内存地址的指针变量。如果错误进 行此指针变量的操作,有可能改写系统内存区域。 如果改写系统内存区域,软件将意外停机(通过看门狗检查 功能检测出来,切断伺服,关闭系统。)、发生报警导致机器人 运行停止、示教器不能操作等严重问题的发生。 16-3 HW1483597-C

第67页

HW1483597-C 16 编程 16.7 运行控制样本程序 16.7 运行控制样本程序 16.7.1 运行控制样本程序 16.7.1.1 概要 用机器人的机械手拿起工件放入托盘的程序示例进行解说。 16.7.1.2 样本程序 将图示 0 到 5 的位置数据事先存储进位置变量。读取这些位置变量,发送 至目标。 /* mp_main.c - MotoPlus Test Application for Real Time Process */ #include \"motoPlus.h\" void mpTask1(); void mpTask2(); //GLOBAL DATA DEFINITIONS int nTaskID1; int nTaskID2; static int handOn(void); static int handOff(void); void mpUsrRoot(int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7, int arg8, int arg9, int arg10) { //TODO: Add additional intialization routines. //Creates and starts a new task in a seperate thread of execution. //All arguments will be passed to the new task if the function //prototype will accept them. nTaskID1 = mpCreateTask(MP_PRI_TIME_NORMAL, MP_STACK_SIZE, (FUNCPTR)mpTask1, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); 16-4 HW1483597-C

第68页

HW1483597-C 16 编程 16.7 运行控制样本程序 nTaskID2 = mpCreateTask(MP_PRI_TIME_NORMAL, MP_STACK_SIZE, (FUNCPTR)mpTask2,arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); //Ends the initialization task. mpExitUsrRoot; } void mpTask1(void) { int rc; int i; int id; int timeout, delay; int grpNo; MP_SPEED spd; MP_TARGET target; MP_USR_VAR_INFO varInfo; // timeout = 30[sec] timeout = 30000 / mpGetRtc(); delay = 1000 / mpGetRtc(); //TODO: Add the code for this task FOREVER { memset(\&varInfo, 0, sizeof(varInfo)); varInfo.var_type = MP_VAR_B; varInfo.var_no = 0; // waiting for start event. printf(\"\

\"); printf(\"... waiting for start event.\

\"); while (varInfo.val.b == 0) { mpTaskDelay(delay); if ((rc = mpGetUserVars(\&varInfo)) < 0) { break; } 16-5 HW1483597-C

第69页

HW1483597-C 16 编程 16.7 运行控制样本程序 } if (rc < 0) { printf(\"%d = mpGetUserVars(MP_VAR_B)\

\", rc); continue; } varInfo.val.b = 0; // clear event. mpPutUserVars(\&varInfo); // get group No. if ((grpNo = mpCtrlGrpId2GrpNo(MP_R1_GID)) < 0) { printf(\"%d = mpCtrlGrpId2GrpNo(MP_R1_GID)\

\", grpNo); continue; } // initialize motion control. mpMotStop(0); mpMotTargetClear(0x0f, 0); // send targets. if ((rc = mpMotSetCoord(grpNo, MP_BASE_TYPE, 0)) < 0) { printf(\"%d = mpMotSetCoord()\

\", rc); continue; } memset(\&spd, 0, sizeof(spd)); spd.v = 500; // 50.0[mm/sec] if ((rc = mpMotSetSpeed(grpNo, \&spd)) < 0) { printf(\"%d = mpMotSetSpeed()\

\", rc); continue; } for (i = 1; i < 6; i++) { printf(\"send No.%d target.\

\", i); 16-6 HW1483597-C

第70页

HW1483597-C 16 编程 16.7 运行控制样本程序 memset(\&target, 0, sizeof(target)); target.id = i; target.intp = MP_MOVL_TYPE; varInfo.var_type = MP_VAR_P; varInfo.var_no = i; if ((rc = mpGetUserVars(\&varInfo)) < 0) { printf(\"%d = mpGetUserVars(MP_VAR_P)\

\", rc); break; } else { memcpy(target.dst.joint, varInfo.val.p.data, sizeof(target.dst.joint)); } if ((rc = mpMotTargetSend((1 << grpNo), \&target, timeout)) < 0) { printf(\"%d = mpMotTargetSend()\

\", rc); break; } } if (rc < 0) { printf(\"sending target failed.\

\"); continue; } handOff(); // open the hand. printf(\"\

\"); printf(\"count down ...\

\"); for (i = 5; i > 0; i--) { printf(\"%d\

\", i); mpTaskDelay(delay); } // motion start! HW1483597-C printf(\"motion start!\

\"); 16-7

第71页

HW1483597-C 16 编程 16.7 运行控制样本程序 if ((rc = mpMotStart(0)) < 0) { printf(\"%d = mpMotStart()\

\", rc); continue; } // ... waiting for target id = 1. id = 1; printf(\"... waiting for target id = %d.\

\", id); if ((rc = mpMotTargetReceive(grpNo, id, NULL, timeout, 0)) < 0) { printf(\"%d = mpMotTargetReceive()\

\", rc); continue; } printf(\"arriving to target id = %d.\

\", id); printf(\"close the hand!\

\"); handOn(); // close the hand. // ... waiting for target id = 4. id = 4; printf(\"... waiting for target id = %d.\

\", id); if ((rc = mpMotTargetReceive(grpNo, id, NULL, timeout, 0)) < 0) { printf(\"%d = mpMotTargetReceive()\

\", rc); continue; } printf(\"arriving to target id = %d.\

\", id); printf(\"open the hand!\

\"); handOff(); // open the hand. // ... waiting for target id = 5. id = 5; printf(\"... waiting for target id = %d.\

\", id); if ((rc = mpMotTargetReceive(grpNo, id, NULL, timeout, 0)) < 0) { printf(\"%d = mpMotTargetReceive()\

\", rc); continue; } printf(\"arriving to target id = %d.\

\", id); 16-8 HW1483597-C

第72页

HW1483597-C 16 编程 16.7 运行控制样本程序 printf(\"\

\"); printf(\"return to home position count down ...\

\"); for (i = 5; i > 0; i--) { printf(\"%d\

\", i); mpTaskDelay(delay); } // send home position. if ((rc = mpMotSetCoord(grpNo, MP_ANGLE_TYPE, 0)) < 0) { printf(\"%d = mpMotSetCoord()\

\", rc); continue; } memset(\&spd, 0, sizeof(spd)); spd.vj = 1000; // 10.00[%] if ((rc = mpMotSetSpeed(grpNo, \&spd)) < 0) { printf(\"%d = mpMotSetSpeed()\

\", rc); continue; } printf(\"send home position.\

\"); memset(\&target, 0, sizeof(target)); target.id = id = 0; target.intp = MP_MOVJ_TYPE; varInfo.var_type = MP_VAR_P; varInfo.var_no = 0; if ((rc = mpGetUserVars(\&varInfo)) < 0) { printf(\"%d = mpGetUserVars(MP_VAR_P)\

\", rc); continue; } else { memcpy(target.dst.joint, varInfo.val.p.data, sizeof(target.dst.joint)); } 16-9 HW1483597-C

第73页

HW1483597-C 16 编程 16.7 运行控制样本程序 if ((rc = mpMotTargetSend((1 << grpNo), \&target, timeout)) < 0) { printf(\"%d = mpMotTargetSend()\

\", rc); break; } if ((rc = mpMotTargetReceive(grpNo, id, NULL, timeout, 0)) < 0) { printf(\"%d = mpMotTargetReceive()\

\", rc); continue; } printf(\"complete!\

\"); mpTaskDelay(delay); } } static int handOn(void) { MP_IO_DATA req; req.ulAddr = 10010; req.ulValue = 1; return (mpWriteIO(\&req, 1)); } static int handOff(void) { MP_IO_DATA req; req.ulAddr = 10010; req.ulValue = 0; return (mpWriteIO(\&req, 1)); } void mpTask2(int arg1, int arg2) { //TODO: Add the code for this task } 16-10 HW1483597-C

第74页

HW1483597-C 16 编程 16.7 运行控制样本程序 16.7.2 独立控制样本程序 16.7.2.1 概要 对 2 台机器人的运行程序示例进行解说。 R1 和 R2 向图 (1) 开始同时运行,同时到达目标位置。然后 R1 和 R2 各自 独立 (2) 向 (4) 非同步运行。最后再次向 (1) 开始同时运行,同时到达目标 位置。 事先读取登录进位置变量的位置,从图示 (1) 到 (4) 的目标位置运行。 16-11 HW1483597-C

第75页

HW1483597-C 16 编程 16.7 运行控制样本程序 16.7.2.2 样本程序 /* mp_main.c - MotoPlus Test Application for Real Time Process */ #include \"motoPlus.h\" // (2) // R1, R2 #define GROUP_NUM (5) #define TARGET_NUM // void mpTask1(); void mpTask2(); //GLOBAL DATA DEFINITIONS int nTaskID1; int nTaskID2; enum { START_TARGET, POS1_TARGET, POS2_TARGET, POS3_TARGET, END_TARGET, }; void mpUsrRoot(int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7, int arg8, int arg9, int arg10) { //TODO: Add additional intialization routines. //Creates and starts a new task in a seperate thread of execution. //All arguments will be passed to the new task if the function //prototype will accept them. nTaskID1 = mpCreateTask(MP_PRI_TIME_NORMAL, MP_STACK_SIZE, (FUNCPTR)mpTask1, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); nTaskID2 = mpCreateTask(MP_PRI_TIME_NORMAL, MP_STACK_SIZE, (FUNCPTR)mpTask2, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); //Ends the initialization task. HW1483597-C mpExitUsrRoot; 16-12

第76页

HW1483597-C 16 编程 16.7 运行控制样本程序 } void mpTask1(void) { //TODO: Add the code for this task int rc; int i; int grp; int grpNoR1, grpNoR2; int timeout, delay; MP_SPEED spd; MP_USR_VAR_INFO varInfo; MP_TARGET target[TARGET_NUM][GROUP_NUM]; // timeout = 60[sec] timeout = 60000 / mpGetRtc(); delay = 1000 / mpGetRtc(); FOREVER { memset(\&varInfo, 0, sizeof(varInfo)); varInfo.var_type = MP_VAR_B; varInfo.var_no = 0; // waiting for start event. printf(\"\

\"); printf(\"... waiting for start event.\

\"); while (varInfo.val.b == 0) { mpTaskDelay(delay); if ((rc = mpGetUserVars(\&varInfo)) < 0) { break; } } if (rc < 0) { printf(\"%d = mpGetUserVars(MP_VAR_B)\

\", rc); 16-13 HW1483597-C

第77页

HW1483597-C 16 编程 16.7 运行控制样本程序 continue; } varInfo.val.b = 0; // clear event. mpPutUserVars(\&varInfo); if ((grpNoR1 = mpCtrlGrpId2GrpNo(MP_R1_GID)) < 0) { printf(\"%d = mpCtrlGrpId2GrpNo(MP_R1_GID)\

\", grpNoR1); continue; } if ((grpNoR2 = mpCtrlGrpId2GrpNo(MP_R2_GID)) < 0) { printf(\"%d = mpCtrlGrpId2GrpNo(MP_R2_GID)\

\", grpNoR2); continue; } grp = (1 << grpNoR1) | (1 << grpNoR2); // initialize motion control. mpMotStop(0); mpMotTargetClear(0x0f, 0); // set speed memset(\&spd, 0, sizeof(spd)); spd.v = 230; // 23.0 mm/s if ((rc = mpMotSetSpeed(grpNoR1, \&spd)) < 0) { printf(\"%d = mpMotSetSpeed(R1)\

\", rc); continue; } spd.v = 100; // 10.0 mm/s if ((rc = mpMotSetSpeed(grpNoR2, \&spd)) < 0) { printf(\"%d = mpMotSetSpeed(R2)\

\", rc); continue; } 16-14 HW1483597-C

第78页

HW1483597-C 16 编程 16.7 运行控制样本程序 // set coordinate system. if ((rc = mpMotSetCoord(grpNoR1, MP_BASE_TYPE, 0)) < 0) { printf(\"%d = mpMotSetCoord(R1)\

\", rc); continue; } if ((rc = mpMotSetCoord(grpNoR2, MP_BASE_TYPE, 0)) < 0) { printf(\"%d = mpMotSetCoord(R2)\

\", rc); continue; } // get destination position from P variable. memset(target, 0, sizeof(target)); for (i = 0; i < TARGET_NUM; i++) { // R1 target[i][grpNoR1].id = (i + 1); target[i][grpNoR1].intp = MP_MOVL_TYPE; varInfo.var_type = MP_VAR_P; varInfo.var_no = i; if ((rc = mpGetUserVars(\&varInfo)) < 0) { printf(\"%d = mpGetUserVars()\

\", rc); break; } else { memcpy(target[i][grpNoR1].dst.joint, varInfo.val.p.data, sizeof(varInfo.val.p.data)); } // R2 target[i][grpNoR2].id = (i + 10); target[i][grpNoR2].intp = MP_MOVL_TYPE; varInfo.var_type = MP_VAR_P; 16-15 HW1483597-C

第79页

HW1483597-C 16 编程 16.7 运行控制样本程序 varInfo.var_no = (i + 10); if ((rc = mpGetUserVars(\&varInfo)) < 0) { printf(\"%d = mpGetUserVars()\

\", rc); break; } else { memcpy(target[i][grpNoR2].dst.joint, varInfo.val.p.data, sizeof(varInfo.val.p.data)); } } if (rc < 0) { continue; } // set task number. if ((rc = mpMotSetTask(grpNoR1, 0)) < 0) { printf(\"%d = mpMotSetTask(R1)\

\", rc); continue; } if ((rc = mpMotSetTask(grpNoR2, 0)) < 0) { printf(\"%d = mpMotSetTask(R2)\

\", rc); continue; } // send target. if ((rc = mpMotTargetSend(grp, target[START_TARGET], timeout)) < 0) { printf(\"%d = mpMotTargetSend(%d)\

\", rc, START_TARGET); continue; } // set task number (R1: task1, R2: task0). 16-16 HW1483597-C

第80页

HW1483597-C 16 编程 16.7 运行控制样本程序 if ((rc = mpMotSetTask(grpNoR1, 1)) < 0) { printf(\"%d = mpMotSetTask(R1)\

\", rc); continue; } // send independent control targets. if ((rc = mpMotTargetSend(grp, target[POS1_TARGET], timeout)) < 0) { printf(\"%d = mpMotTargetSend(%d)\

\", rc, POS1_TARGET); continue; } if ((rc = mpMotTargetSend(grp, target[POS2_TARGET], timeout)) < 0) { printf(\"%d = mpMotTargetSend(%d)\

\", rc, POS2_TARGET); continue; } // send target for only R2 group. if ((rc = mpMotTargetSend((1 << grpNoR2), target[POS3_TARGET], timeout)) < 0) { printf(\"%d = mpMotTargetSend(%d)\

\", rc, POS3_TARGET); continue; } // reset task number. if ((rc = mpMotSetTask(grpNoR1, 0)) < 0) { printf(\"%d = mpMotSetTask(R1)\

\", rc); continue; } // send target. if ((rc = mpMotTargetSend(grp, target[END_TARGET], timeout)) < 0) { printf(\"%d = mpMotTargetSend(%d)\

\", rc, END_TARGET); continue; 16-17 HW1483597-C

第81页

HW1483597-C 16 编程 16.7 运行控制样本程序 } printf(\"sending target is complete!\

\"); // motion start! printf(\"motion start!\

\"); if ((rc = mpMotStart(0)) < 0) { printf(\"%d = mpMotStart()\

\", rc); continue; } if ((rc = mpMotTargetReceive(grpNoR1, TARGET_NUM, NULL, timeout, 0)) < 0) { printf(\"%d = mpMotTargetReceive(R1)\

\", rc); continue; } printf(\"complete!\

\"); mpTaskDelay(delay); } } void mpTask2(int arg1, int arg2) { //TODO: Add the code for this task } 16-18 HW1483597-C

第82页

HW1483597-C 16 编程 16.7 运行控制样本程序 16.7.3 协调控制样本程序 16.7.3.1 概要 对机器人与工装轴协调将工件从一端移动至另一端的程序示例进行解说。 事先读取登录进位置变量的位置,作为运行的开始位置以及到达位置 运行。 16-19 HW1483597-C

第83页

HW1483597-C 16 编程 16.7 运行控制样本程序 16.7.3.2 样本程序 /* mp_main.c - MotoPlus Test Application for Real Time Process */ #include \"motoPlus.h\" // (2) // R1, S1 #define GROUP_NUM (2) #define TARGET_NUM // void mpTask1(); void mpTask2(); //GLOBAL DATA DEFINITIONS int nTaskID1; int nTaskID2; void mpUsrRoot(int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7, int arg8, int arg9, int arg10) { //TODO: Add additional intialization routines. //Creates and starts a new task in a seperate thread of execution. //All arguments will be passed to the new task if the function //prototype will accept them. nTaskID1 = mpCreateTask(MP_PRI_TIME_NORMAL, MP_STACK_SIZE, (FUNCPTR)mpTask1, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); nTaskID2 = mpCreateTask(MP_PRI_TIME_NORMAL, MP_STACK_SIZE, (FUNCPTR)mpTask2, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); //Ends the initialization task. mpExitUsrRoot; } void mpTask1(void) { //TODO: Add the code for this task int rc; 16-20 HW1483597-C

第84页

HW1483597-C 16 编程 16.7 运行控制样本程序 int i; int grp; int grpNoR1, grpNoS1; int timeout, delay; MP_SPEED spd; MP_TARGET target[TARGET_NUM][GROUP_NUM]; MP_USR_VAR_INFO varInfo; // timeout = 60[sec] timeout = 60000 / mpGetRtc(); delay = 1000 / mpGetRtc(); FOREVER { memset(\&varInfo, 0, sizeof(varInfo)); varInfo.var_type = MP_VAR_B; varInfo.var_no = 0; // waiting for start event. printf(\"\

\"); printf(\"... waiting for start event.\

\"); while (varInfo.val.b == 0) { mpTaskDelay(delay); if ((rc = mpGetUserVars(\&varInfo)) < 0) { break; } } if (rc < 0) { printf(\"%d = mpGetUserVars(MP_VAR_B)\

\", rc); continue; } varInfo.val.b = 0; // clear event. mpPutUserVars(\&varInfo); // initialize motion control. HW1483597-C 16-21

第85页

HW1483597-C 16 编程 16.7 运行控制样本程序 mpMotStop(0); mpMotTargetClear(0x0f, 0); if ((grpNoR1 = mpCtrlGrpId2GrpNo(MP_R1_GID)) < 0) { printf(\"%d = mpCtrlGrpId2GrpNo(MP_R1_GID)\

\", grpNoR1); continue; } if ((grpNoS1 = mpCtrlGrpId2GrpNo(MP_S1_GID)) < 0) { printf(\"%d = mpCtrlGrpId2GrpNo(MP_S1_GID)\

\", grpNoS1); continue; } grp = (1 << grpNoR1) | (1 << grpNoS1); // reset coordinated motion. if ((rc = mpMotResetSync(grpNoR1)) < 0) { printf(\"%d = mpMotResetSync(R1)\

\", rc); continue; } // set speed. memset(\&spd, 0, sizeof(spd)); spd.v = 230; // 23.0 mm/s if ((rc = mpMotSetSpeed(grpNoR1, \&spd)) < 0) { printf(\"%d = mpMotSetSpeed(R1)\

\", rc); continue; } memset(\&spd, 0, sizeof(spd)); spd.vj = 5000; // 50.00 % if ((rc = mpMotSetSpeed(grpNoS1, \&spd)) < 0) { printf(\"%d = mpMotSetSpeed(S1)\

\", rc); continue; 16-22 HW1483597-C

第86页

HW1483597-C 16 编程 16.7 运行控制样本程序 } // set coordinate system, if ((rc = mpMotSetCoord(grpNoR1, MP_BASE_TYPE, 0)) < 0) { printf(\"%d = mpMotSetCoord(R1)\

\", rc); continue; } if ((rc = mpMotSetCoord(grpNoS1, MP_PULSE_TYPE, 0)) < 0) { printf(\"%d = mpMotSetCoord(S1)\

\", rc); continue; } // get destination position from P variable (or EX variable). memset(target, 0, sizeof(target)); for (i = 0; i < TARGET_NUM; i++) { // R1 target[i][grpNoR1].id = (i + 1); target[i][grpNoR1].intp = MP_MOVL_TYPE; varInfo.var_type = MP_VAR_P; varInfo.var_no = i; if ((rc = mpGetUserVars(\&varInfo)) < 0) { printf(\"%d = mpGetUserVars()\

\", rc); break; } else { memcpy(target[i][grpNoR1].dst.joint, varInfo.val.p.data, sizeof(varInfo.val.p.data)); } // S1 target[i][grpNoS1].id = (i + 10); target[i][grpNoS1].intp = MP_MOVJ_TYPE; 16-23 HW1483597-C

第87页

HW1483597-C 16 编程 16.7 运行控制样本程序 varInfo.var_type = MP_VAR_EX; varInfo.var_no = i; if ((rc = mpGetUserVars(\&varInfo)) < 0) { printf(\"%d = mpGetUserVars()\

\", rc); break; } else { memcpy(target[i][grpNoS1].dst.joint, varInfo.val.ex.data, sizeof(varInfo.val.ex.data)); } } if (rc < 0) { continue; } // send target. i = 0; if ((rc = mpMotTargetSend(grp, target[i], timeout)) < 0) { printf(\"%d = mpMotTargetSend(%d)\

\", rc, i); continue; } // set coordinated motion. if ((rc = mpMotSetSync(grpNoR1, grpNoS1, 0)) < 0) { printf(\"%d = mpMotSetSync()\

\", rc); continue; } // send coordinated motion target. i++; if ((rc = mpMotTargetSend(grp, target[i], timeout)) < 0) { 16-24 HW1483597-C

第88页

HW1483597-C 16 编程 16.7 运行控制样本程序 printf(\"%d = mpMotTargetSend(%d)\

\", rc, i); continue; } printf(\"sending target is complete!\

\"); // motion start! printf(\"motion start!\

\"); if ((rc = mpMotStart(0)) < 0) { printf(\"%d = mpMotStart()\

\", rc); continue; } if ((rc = mpMotTargetReceive(grpNoR1, TARGET_NUM, NULL, timeout, 0)) < 0) { printf(\"%d = mpMotTargetReceive()\

\", rc); continue; } printf(\"complete!\

\"); mpTaskDelay(delay); } } void mpTask2(int arg1, int arg2) { //TODO: Add the code for this task } 16-25 HW1483597-C

第89页

HW1483597-C 16 编程 16.8 调试时的现象与设想的编码上的问题 / 调查方法 16.8 调试时的现象与设想的编码上的问题 / 调查方法 16.8.1 示教器画面因 \"Starting up system Start Online Process\" 停止, YRC1000 不启动  主要原因 1:定义超过堆栈大小的本地变量,启动时访问(写入)。 如果 AIF01 基板的 7 segLED 变为 C.(点闪烁),很可能超过了任务的堆栈 区。 首先请在维护模式下删除 MotoPlus 应用,确认能正常启动。 如果正常,很可能 MotoPlus 应用的程序有问题。 堆栈大小为 1 个任务 20Kbyte。请确认在 MotoPlus 应用的各个函数的本地 变量定义时,是否定义了超出的较大变量。  主要原因 2:在任务优先级高于 ME_NORMAL 的高优先级的任务中,标签 状态的更改在具有无限等待状态的 while loop 执行,而不会延时任务。 首先请在维护模式下删除 MotoPlus 应用,确认能正常启动。 如果正常,很可能 MotoPlus 应用的程序有问题。 如果 AIF01 基板的 7 segLED 变为 D.(点闪烁),请在应用的高优先级的任 务中不要使用 mpTaskDelay(),确认是否为无限等待。 16.8.2 MotoPlus 应用看起来像不运行的现象  主要原因 1:定义了超出堆栈大小的本地变量,以某种条件访问(写入), 破坏了堆栈区。 MotoPlus 应用破坏了堆栈区时, VxWorks 检测出,可能将此任务变为错误 状态,停止运行。在有可能发生异常的任务中,请追加处理定期对 I/O 进 行 ON/OFF。如果此任务在运行,在示教器的 I/O 画面,可以确认指定的 I/ O 的 ON/OFF。如果不能确认 ON/OFF,有可能任务没有在运行。这种情况 请确认以下项目。 • 本地变量的定义是否大于堆栈大小 • 定义了排列的本地变量的排列编号是否超出了设想的最大值 • 本地变量相关的指针操作是否错误 16-26 HW1483597-C

第90页

HW1483597-C 16 编程 16.8 调试时的现象与设想的编码上的问题 / 调查方法 16.8.3 发生报警 4479 \"MotoPlus MM 任务看门狗错误  主要原因 1:在任务优先级高于常规优先级(MP_PRI_TIME_NORMAL) 的高优先级任务中,标签状态的更改在具有无限等待状态的 while loop 中 执行,而不延时任务。 请在启动后以某种条件在应用的高优先级任务中,不使用 mpTaskDelay(), 确认是否为无限等待。  主要原因 2:在任务优先级高于常规优先级(MP_PRI_TIME_NORMAL) 的高优先级任务中,正在执行需要进行长时间处理的处理。 启动后,请在特定的条件下,确认是否执行了需要长时间处理的处理。如 果有这种处理,请修改设定将此处理转移至常规优先级的任务中。 16.8.4 示教器的画面显示和键的应答慢  主要原因 1:在任务优先级高于常规优先级(MP_PRI_TIME_NORMAL) 的高优先级任务中,正在执行需要进行长时间处理的处理。 启动后,请在特定的条件下,确认是否执行了需要长时间处理的处理。如 果执行的处理超过了 1msec,虽不至于「16.8.3 “ 发生报警 4479  \"MotoPlus MM 任务看门狗错误 ”」,会出现示教器的画面显示和键的应答 慢的现象。  主要原因 2:在任务优先级为常规优先级(MP_PRI_TIME_NORMAL)的 MotoPlus 应用任务中,无 mpTaskDelay() 执行无限等待。 常规优先级的任务与执行示教器的画面显示的任务是同一优先级。在 MotoPlus 应用任务中,如果无 mpTaskDelay() 执行无限等待,则示教器的 画面显示处理时间受压缩,应答变慢。 16.8.5 示教器通信异常,切断 YRC1000 系统伺服电源(意外停机状态)  主要原因 1:因指针操作错误导致发生 CPU 异常。 这种情况, AIF01 基板的 7 segLED 时间系列显示 \"000E-0F3D412D\" (0F3D412D 是异常发生的程序执行地址,根据发生地方有异。)。因 MotoPlus 应用任务中指针控制错误的可能性较高,请通过 printf(),或向用 户变量输出程序执行状态编号,调查异常发生场所。 16-27 HW1483597-C

第91页

HW1483597-C 17 样本程序 17.1 样本程序的概要 17 样本程序 17.1 样本程序的概要 样本程序在 DVD 的 ¥samples。将它复制进 PC 的任一文件夹。(示例复制 进 C:¥MotoPlusData¥samples。)样本的种类为 \"Hello World\"、\"Multi Task control\"、\"UserWatchDog\"、\"Ethernet control\"、\"variable \& IO control\"、 \"RS232C\" 、\"ServoControl\" 七种。各个文件夹里有源文件,按以下步骤可 以确认运行。 1. 执行 MotoPlusIDE,打开 C:¥MotoPlusData¥samples 里的各个文件 夹里的 *.mpProj。 2. 执行 MotoPlusIDE 的菜单的 \"build\" → \"Build project\" 。 3. 有 C:¥MotoPlusData¥samples 的 *.mpProj 的文件夹里的 \"¥out\" 中, 将生成 *.out(执行文件)。 4. 将生成的 *.out 文件安装进 YRC1000。首先,将生成的 OUT 文件复 制进 SD(或 USB 存储器),然后在维护模式下启动 YRC1000,用 \"MotoPlus 应用 \" 菜单中的 \" 加载(用户应用)\" 安装。(详细请参 照「YRC1000 新语言环境 MotoPlus 用户手册(HW1483599)」的 「4 章  应用程序安装与启动」) 5. 常规模式下再次启动 YRC1000。 通过以上操作, YRC1000 启动后,应用程序将自动启动。 DVD 中的样本程序在安装有 IDE 的默认的安装文件夹 (C:¥ProgramFiles¥Yaskawa¥MotoPlusIDE)的环境创建。 从默认变更安装文件夹时,需要对样本项目的构建设定进行 初始化。 详细请参照「YRC1000 新语言环境 MotoPlus 用户手册 (HW1483599)」的「3.7 章 构建设定的变更」。 17-1 HW1483597-C

第92页

HW1483597-C 17 样本程序 17.2 Hello World 的显示 17.2 Hello World 的显示 以下记载了最原始的源代码 \"HELLO WORLD\" 的显示。这是 C:¥MotoPlusData¥sample¥Hello World¥srcHelloWorld 里的 HelloWorld.c。电 源接通后,如果将 PC 连接 TELNET,在 PC 的 TELNET 终端画面 ->Hello World ->Hello World ->Hello World : 以每 2.5 秒重复显示。 //**** HelloWorld.c **** #include \"motoPlus.h\" void mpUsrRoot(int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7, int arg8, int arg9, int arg10) { tid1 = mpCreateTask(MP_PRI_TIME_NORMAL, MP_STACK_SIZE, (FUNCPTR)moto_plus0_task, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); mpExitUsrRoot; } void moto_plus0_task(void) { while (1) { puts(\"Hello World!\"); mpTaskDelay(2500); } } 17-2 HW1483597-C

第93页

HW1483597-C 17 样本程序 17.3 任务控制样本程序 17.3 任务控制样本程序 然后是任务控制的样本。本次对使用了 2 个源代码的示例进行说明。它们 是, C:¥MotoPlusData¥sample¥Multi Task control¥srcMultiTaskCtrl 中的 \"TaskCtl1.c\" 与 \"TaskCtl1.2\"。 第一个源文件 TaskCtl1.c 使用 mpCreateTask() 启动 2 个任务 moto_plus0_task 和 moto_plus1_task,生成 1 个信号量。生成后,自己结 束。 //**** TaskCtl1.c **** #include \"motoPlus.h\" // for GLOBAL DATA DEFINITIONS SEM_ID semid; // for IMPORT API \& FUNCTIONS extern void moto_plus0_task(void); extern void moto_plus1_task(void); // for LOCAL DEFINITIONS static int tid1, tid2; void mpUsrRoot(int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7, int arg8, int arg9, int arg10) { tid1 = mpCreateTask(MP_PRI_TIME_NORMAL, MP_STACK_SIZE, (FUNCPTR)moto_plus0_task, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); tid2 = mpCreateTask(MP_PRI_TIME_NORMAL, MP_STACK_SIZE, (FUNCPTR)moto_plus1_task, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); semid = mpSemBCreate(SEM_Q_FIFO, SEM_EMPTY); // 二进制信号量 puts(\"Exit mpUsrRoot!\"); mpExitUsrRoot; //(or) mpSuspendSelf; } 17-3 HW1483597-C

第94页

HW1483597-C 17 样本程序 17.3 任务控制样本程序 第二个源文件 TaskCtl2.c 记述了 2 个任务 moto_plus0_task 和 moto_plus1_task。 moto_plus0_task 每 2.5 秒向 moto_plus1_task 使用 mpSemGive() 发送信号量。 moto_plus1_task 用 mpSemTake() 接收发送来的 信号量,每接收 1 次在 \"moto_plus1_task Running\" 的后面都将显示接收的 次数。 //**** TaskCtl2.c **** #include \"motoPlus.h\" // for API \& FUNCTIONS extern void moto_plus0_task(void); extern void moto_plus1_task(void); // for DATA extern SEM_ID semid; void moto_plus0_task(void) { puts(\"Activate moto_plus0_task!\"); while (1) { mpSemGive(semid); mpTaskDelay(2500); } } void moto_plus1_task(void) { STATUS status; unsigned int run_cnt; //float get_time; puts(\"Activate moto_plus1_task!\"); run_cnt = 0; while (1) { 17-4 HW1483597-C

第95页

HW1483597-C 17 样本程序 17.3 任务控制样本程序 run_cnt++; status = mpSemTake(semid, WAIT_FOREVER); if (status == ERROR) { printf(\"semTake Error![%d]¥n\", run_cnt); } else { printf(\"moto_plus1_task Running![%d]¥n\", run_cnt); } } } 17-5 HW1483597-C

第96页

HW1483597-C 17 样本程序 17.4 用户看门狗样本程序 17.4 用户看门狗样本程序 下面对用户看门狗的样本程序进行说明。样本程序在「UserWatchDog」文 件夹里。此样本程序由,运行看门狗的高优先级任务 mp_seg_mon_task 和,访问D 变量的任务 mp_para_get_task 构成。用 mp_para_get_task 进行 访问的D 变量作为用于操作看门狗的触发器及参数利用。使用的D 变量记 载在下表中。 变量 意义 备考 D050 D051 mpUsrWdogCreate 函数的执行 执行条件:\"0\" → \"1\" D052 D053 mpUsrWdogDelete 函数的执行 执行条件:\"0\" → \"1\" D054 D055 mpUsrWdogStart 函数的执行 执行条件:\"0\" → \"1\" D056 D058 mpUsrWdogClear 函数的执行 执行条件:\"0\" → \"1\" D059 操作的用户看门狗的索引 0或1 索引 \"0\" 的用户看门狗的延迟时间 单位是[msec] D061 索引 \"1\" 的用户看门狗的延迟时间 单位是[msec] 索引 \"0\" 的用户看门狗的清除间隔 单位是 D062 [x 插补周期] 索引 \"1\" 的用户看门狗的清除间隔 单位是 [x 插补周期] 索引 \"0\" 的用户看门狗的启动及定期 执行条件:\"0\" → \"1\" 清除 索引 \"1\" 的用户看门狗的启动及定期 执行条件:\"0\" → \"1\" 清除 通过将 \"0\" → \"1\" 输入 D050 ~ D053 的各个变量,可以执行用户看门狗 的各个 API。 MotoPlus 最多可以同时运行 2 个用户看门狗定时器。 D054 为指定 2 个 用户看门狗时的索引。 D055,D056 为用户看门狗的延迟时间 [ms]。 D061,D062 是用于「启动」及「定期清除」用户看门狗的触发器。清除的 间隔用 D058,D059 指定。在 D058(D059)× 的每个插补周期都将执行用户 看门狗的清除。如果没有进行延迟时间的清除,在生成用户看门狗时超时 程序函数 fncwdRoutine0, fncwdRoutine1 被执行,向寄存器编号 50 或 51 输 出值。 并且,由于处理用户看门狗的「生成」较花时间,因此在高优先级的任务 中仅执行「启动」及「清除」。 17-6 HW1483597-C

第97页

HW1483597-C 17 样本程序 17.4 用户看门狗样本程序 <样本程序(仅记载主要部分。)> /**** mpMain.c ****/ void mpUsrRoot(int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7, int arg8, int arg9, int arg10) { semid = mpSemBCreate(SEM_Q_FIFO, SEM_EMPTY); ip_tid = mpCreateTask(MP_PRI_IP_CLK_TAKE, MP_STACK_SIZE, (FUNCPTR)mp_seg_mon_task, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); tn_tid = mpCreateTask(MP_PRI_TIME_NORMAL, MP_STACK_SIZE, (FUNCPTR)mp_para_get_task, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); mpExitUsrRoot; } static void mp_para_get_task(void) { FOREVER { GetParameter( ); mpTaskDelay(1000); // 1sec wait; } } static void mp_seg_mon_task(void) { int rc, i; LONG Cnt[2]; LONG DVvalue_last[2]; wdRoutine[0] = (MP_USR_WDG_ROUTINE)fncwdRoutine0; wdRoutine[1] = (MP_USR_WDG_ROUTINE)fncwdRoutine1; GetParameter( ); FOREVER { if (mpClkAnnounce(MP_INTERPOLATION_CLK) == ERROR) 17-7 HW1483597-C

第98页

HW1483597-C 17 样本程序 17.4 用户看门狗样本程序 mpTaskSuspend(ip_tid); for( i = 0; i <2; i++ ) { //D061,D062 if( (DVvalue_last[i] == 0) \&\& (DVvalue[11 + i] == 1) ) { Cnt[i] = 0; rc = mpUsrWdogStart( handle[i] ); } DVvalue_last[i] = DVvalue[11 + i]; if( DVvalue[11 + i] == 1 ) { if( ClearCnt[i] > Cnt[i] ) { ++Cnt[i]; if( ClearCnt[i] == Cnt[i] ) { rc = mpUsrWdogClear( handle[i] ); Cnt[i] = 0; } } } } } } static void GetParameter(void) { int rc; int index; LONG DVvalue050, DVvalue051, DVvalue052, DVvalue053; //Save DVar oldvalue DVvalue050 = DVvalue[0]; //WdogCreate DVvalue051 = DVvalue[1]; //WdogDelete DVvalue052 = DVvalue[2]; //WdogStart DVvalue053 = DVvalue[3]; //WdogClear 17-8 HW1483597-C

第99页

HW1483597-C 17 样本程序 17.4 用户看门狗样本程序 //Get DVar value if( mpGetMultiDVar(50, DVvalue, DVAL_NUM) == 0 ) { //Get index value : D054 if( DVvalue[4] < 2 ) index = (int)DVvalue[4]; else index = 0; //Get delay value: D055,D056 delay[0] = (int)DVvalue[5]; delay[1] = (int)DVvalue[6]; //Get ClearCnt value: D058,D059 ClearCnt[0] = DVvalue[8]; ClearCnt[1] = DVvalue[9]; //WdogCreate if( (DVvalue050 == 0) \&\& (DVvalue[0] == 1) ) //D050 \"0\"->\"1\" handle[index] = mpUsrWdogCreate( delay[index] , wdRoutine[index] ); //WdogDelete if( (DVvalue051 == 0) \&\& (DVvalue[1] == 1) ) //D051 \"0\"->\"1\" rc = mpUsrWdogDelete( handle[index] ); //WdogStart if( (DVvalue052 == 0) \&\& (DVvalue[2] == 1) ) //D052 \"0\"->\"1\" rc = mpUsrWdogStart( handle[index] ); //WdogClear if( (DVvalue053 == 0) \&\& (DVvalue[3] == 1) ) //D053 \"0\"->\"1\" rc = mpUsrWdogClear( handle[index] ); } } static void fncwdRoutine0( MP_WDG_HANDLE lhandle ) { if( WriteIO(1000050, 50) != 0) puts(\"Error!! (WriteIO_0)\

\"); 17-9 HW1483597-C

第100页

HW1483597-C 17 样本程序 17.4 用户看门狗样本程序 else printf(\"wdRoutine0!! (WriteIO_0) [handle = %d]\

\", lhandle); } static void fncwdRoutine1(MP_WDG_HANDLE lhandle ) { if( WriteIO(1000051, 51) != 0) puts(\"Error!! (WriteIO_1)\

\"); else printf(\"wdRoutine1!! (WriteIO_1) [handle = %d]\

\", lhandle); } 17-10 HW1483597-C

云展网——上百万用户在此分享了PDF文档。上传您的PDF转换为3D翻页电子书,自动生成链接和二维码(独立电子书),支持分享到微信及网站!
收藏
转发
下载
免费制作
其他案例
更多案例
免费制作
x
{{item.desc}}
下载
{{item.title}}
{{toast}}