EPICS电机支持(asynMotor)

EPICS电机支持

1) 顶层对象是EPICS motor记录

已经对这个对象编写了很多代码:spec,IDL和Python类等

2)下一层是EPICS设备支持

了解motor记录,与驱动会话

3)最底层是EPICS驱动

对motor记录一无所知,与硬件会话

当前推荐的设备和驱动开发框架是asynMotor(模型3)

asynPortDriver用于扩展这个框架用于不被motorRecord支持的硬件特性。

asynMotor(模型3)

1)从2011年,在synApps motor模块中出现。

2)C++模型。

3)两个基类,asynMotorController和asynMotorAxis。

4)基类提供了大部分功能,只需要编写设备相关的实现。

5)易于支持控制器相关的特性。

6)在驱动API中对协同轮廓移动的直接支持。

基于synApps的motor驱动开发

1) synApps motor模块(需要ASYN,BUSY,IPAC和SNCSEQ)

        a) motorRecord($(MOTOR)/motorApp/MotorSrc)

        b) asynMotor设备支持(devMotorAsyn.c)

        c) asynMotor驱动基类

                i) asynMotorController.h, .cpp
                ii) asynMotorAxis.h, .cpp

 

2) Motor驱动代码要实现asynMotor基类的控制器相关方法

        a) <Name>MotorDriver.cpp

        b) <Name>MotorDriver.h

        c) <Name>MotorSupport.dbd

’控制器‘构造器做什么?

1) 创建一个实现了一个'真实'电机控制器的控制器对象(asynPortDriver)。

        电机控制器硬件必须初始化

2)为在'CreateController'参数中,为每个请求的电机通道调用轴数次'Axis'构造器。

3)启动Poller任务,将更新所有电机通道的状态。

4)实现非-motorRecord特性。

  • 用于其它控制器参数的asynPortDriver方法
  • 内建"轮廓移动"(协同多轴)方法

ACRController构造器

在从st.cmd调用iocInit()前:asynMotor.cmd(BCDA标准IOC启动文件)

ACR示例:motor/iocWithAsyn/st.cmd.acr

# portName, asynPort, num of axes, active poll period(ms), idle poll period(ms)

ACRCreateController("ACR1", "ARIES", 1, 20, 1000)

extern "C" int ACRCreateController(const char * portName, const char * ACRPortName, int numAxes,int movingPollPeriod,int idlePollPeriod)
{new ACRController(portName, ACRPortName, numAxes, movingPollPeriod/1000., idlePollPeriod/1000.)
}

创建一个新的ACRController对象。

参数:

  • [in] portName:将为这个驱动创建的asyn端口的名称。
  • [in] ACRPortName:先前创建的为连接ACR控制器的drvAsynIPPort的名称。
  • [in] numAxes:这个控制器支持的轴数。
  • [in] movingPollPeriod:当任何轴在移动时,轮询之间的时间。
  • [in] idlePollPeriod:当没有轴在移动时,轮询之间的时间。
ACRController::ACRController(const char * portName, 
const char * ACRPortName, int numAxes, double movingPollPeriod, double idlePollPeriod)
: asynMotorController(portName, numAxes, NUM_ACR_PARAMS, asynUInt32DigitalMask,
asynUInt32DigitalMask, ASYN_CANBLOCK | ASYN_MULTIDEVICE, 1, 0, 0)
asynMotorController:asynMotorController(const char * portName,int         numAxes,int         numParams,int         interfaceMask,int         interruptMask,int         asynFlags,int         autoConnect,int         priority,int         stackSize
)

 创建一个新的asynMotorController对象。所有参数只是被传递给了asynPortDriver基类的构造器。在调用这个基类构造器后,这个方法创建了在asynMotorDriver.h中定义的电机参数。

ACRController::ACRController(const char * portName, 
const char * ACRPortName, int numAxes, double movingPollPeriod, double idlePollPeriod)
: asynMotorController(portName, numAxes, NUM_ACR_PARAMS, asynUInt32DigitalMask,asynUInt32DigitalMask, ASYN_CANBLOCK | ASYN_MULTIDEVICE, 1,  // 自动连接0, 0) // 默认优先级和栈尺寸
{...// 创建控制器相关的参数createParam(ACRJerkString,            asynParamFloat64,    &ACRJerk_);createParam(ACRReadBinaryIOString,    asynParamInt32,      &ACRReadBinaryIO_);// 连接到ACR控制器status = pasynOctetSyncIO->connect(ACRPortName, 0, &pasynUserContorller_, NULL);// 关闭命令回送sprintf(outString_, "ECHO 4");writeController();// 创建轴对象for (axis = 0; axis < numAxes; axis++){new ACRAxis(this, axis);}startPoller(movingPollPeriod, idlePollPeriod, 2);
}
ACRAxis::ACRAxis(class ACRController * pc, int axisNo)

创建一个ACRAxis对象。

参数:

[in] pC:指向这个轴所属的ACRController的指针

[in]axisNo:这个轴的索引,范围从0到pc->numAxes_-1。

初始化寄存器数目等。

asynStatus asynMotorController::startPoller(double movingPollPeriod,double indlePollPeriod,int    forcedFastPolls)

启动这个电机的poller线程。派生类将在它们构造器接近末尾处调用这个方法。派生类一般可以使用这个poller线程的基类实现,但如果需要,可以自动重新实现。

参数:

  • [in] movingPollPeriod:当电机正在运动时,轮询之间的时间。
  • [in] idlePollPeriod:当没有轴运动时,轮询之间的时间。
  • [in] forcedFastPolls:在唤醒这个poller后,执行movingPollPeriod的次数。对于在告诉一个轴已经启动后,不立即报告那个轴正在移动的控制器,这需要非0。

asynMotorController方法ACRController自定义参数

asynStatus ACRController::writeFloat64(asynUser * pasynUser, epicsFloat64 value)
{int function = pasynUser->reason;asynStatus status = asynSuccess;ACRAxis * pAxis = getAxis(pasynUser);static const char * functionName = "writeFloat64";if (function == ACRJerk_){sprintf(outString_, "%s JOG JRK %f", pAxis->axisName_, value);}else{/* 调用基类方法 */status = asynMotorController::writeFloat64(pasynUser, value);}/* 进行回调, 因而更高层看到任何变化 */pAxis->callParamCallbacks();
}
asynStatus ACRController::writeFloat64(asynUser * pasynUser, epicsFloat64 value)

当客户端调用pasynFloat64->write()时,被调用。

从pasynUser中提取功能和轴编号。在参数库中设置这个值。如果功能时ACRJerk_,它设置控制器中的jerk值。对这个pasynUser->reason和地址,调用任何已注册的回调。对于所有其它功能,它调用asynMotorController::writeFloat64()。

参数:

[in] pasynUser:编码reasone和地址的asynUser结构体。

[in] value:要写的值。

对asynMotorController的重新实现。

asynMotorAxis构造器

创建一个Axis对象,它自定义为一个特定的电机控制器。

1)在控制器硬件中的电机轴必须初始化。

2)根据motorRecord表征motorRecord:GrainSupport, HasEncoder

3)实现提供所有可用motorRecord功能的方法:move,moveVelocity, home, setPosition,...

实现'report'方法

ACRAxis

ACRAxis::ACRAxis(ACRController * pc, int axisNo) : asynMotorAxis(pC, axisNo), pC_(pC)

ACRAxis::ACRAxis(ACRController * pc, int axisNo) 

创建一个新的asynMotorAxis对象。

参数:

[in] pC:指向这个轴所属的asynMotorController的指针。

[in] axisNo:这个轴的索引号,范围从0到pC->numAxies_ - 1。

检查那个pC不是NULL,并且axisNo在有效范围内。在pC->pAxes[axisNo_]中设置一个指向自身的指针。连接pasynUser_为这个asyn端口和axisNo。

asynMotorAxis方法

ACRAxis Move

asynStatus ACRAxis::move(double position,int    relative,double minVelocity,double maxVelocity,double acceleration)

移动电机到一个绝对位置或者通过相对量。

参数:

[in] position:(如果relative=0)移动到绝对位置,或者(如果relative=1)要移动的相对位置。(单位steps)。

[in] relative:表明相对移动(1)或者绝对移动(0)的标记。

[in] minVelocity:初始速度,经常称为基速度。单位=steps/sec。

[in] maxVelocity:最大速度,经常称为回转速度。单位=steps/sec。

[in] acceleration:加速度值。单位=steps/sec/sec。

asynStatus ACRAxis::move(double position, int relative, double minVelocity,double maxVelocity, double acceleration)
{sprintf(pc_->outString_, "%s JOG ACC %f", axisName_, acceleration/pulsesPerUnit_);status = pC_->writeController();sprintf(pc_->outString_, "%s JOG VEL %f",  axisName_, maxVelocity/pulsePerUnit_);status = pc_->writeCOntroller();if (relative){sprintf(pC_->outString_, "%c:%s JOG INC %f", CtlY, axisName_, position/pulsePerUnit_);status = pC_->writeController();}else{sprintf(pC_->outString_, "%c:%s JOG ABS %f", CtlY, axisName_, position/pulsesPerUnit_);status = pC_->writeController();}
}

ACRAxis MoveVelocity

asynStatus ACRAxis::moveVelocity(double minVelocity, double maxVelocity, double acceration)

以固定速度移动电机,直到告诉电机停止。

参数:

[in] minVelocity:初始速度,经常被称为基速度。单位=steps/sec。

[in] maxVelocity:最大速度,经常称为回转速度。单位=steps/sec。

[in] acceration:加速度值。单位=steps/sec/sec。

对来自asynMotorAxis的重新实现。

ACRAxis Poll

asynStatus ACRAxis::poll(bool * moving)

查询这个轴。这个函数读取控制器位置,编码器位置,限位状态,移动状态和驱动上电状态。它为它轮询的每项调用setIntegerParam()和setDoubleParam(),并且接着在末尾调用callParamCallbacks()。

参数:

[out] moving:一个标记,设置它来表明这个轴是移动(1)或者结束(0)。

 

asynStatus ACRAxis::poll(bool * moving)
{// 读取当前编码器位置sprintf(pC_->outString, "?P%d", encoderPostionReg_);comStatus = pC_->writeReadController();if (comStatus) goto skip;encoderPosition_ = atof(pC_->inString);setDoubleParam(pC_->motorEncoderPosition_, encoderPostion);// 读取当前标记sprintf(pC_->outString_, "?P%d", flagReg_);comStatus = pC_->writeReadController();if (comStatus) goto skip;currentFlag_ = atoi(pC_->inString_);done = (currentFlags & 0x1000000) ? 0: 1;setIntegerParam(pC_->motorStatusDone_, done);* moving = done ? false : true;// 读取当前状态sprintf(pC_->outString, "?P%d", limitsReg_);comStatus = pC_->writeReadController();if (comStatus) goto skip;currentLimits_ = atoi(pC->inString_);limit = (currentLimts_ & 0x1) ? 1:0;setIntegerParam(pC_->motorStatusHighLimit_, limit);limit = (currentLimits_ & 0x2)?1:0;setIntegerParam(pC_->motorStatusAtHome_, limit);skip:setIntegerParam(pC_->motorStatusProblem_, comStatus ? 1: 0);callParamCallbacks();return comStatus ? asynError : asynSuccess;
}

ACRAxis Home

asynStatus ACRAxis::home(double minVelocity, double maxVelocity, double acceleration, int forwards)

移动电机到home位置。

参数:

[in] minVelocity:初始速度,经常称为基速度。单位=steps/sec。

[in] maxVelocity:最大速度,经常称为回转速度。单位=steps/sec。

[in] acceraltion:加速度值。单位=steps/sec/sec。

[in] forwards:表明正(1)反(0)方向移动电机的标记。某些控制器需要被告知方向,另一些直到用哪种方式移动到home。

ACRAxis Report

void ACRAxis::report(FILE *fp, int level)

报告驱动的状态。

参数:

[in] fp:文件指针,报告信息将写入这个文件。

[in] level:详细程度。

如果detail>0,则输出每个轴的信息。在打印控制器相关信息后,调用asynMotorController::report()。

ACRAxis setPosition

asynStatus ACRAxis::setPosition(double position)

设置电机的当前值。

参数:

[in] position:新的绝对电机位置应该被设置到硬件中。Units=Steps。

ACRAxis Stop

asynStatus ACRAxis::stop(double acceleration)

停止电机。

参数:

[in] acceleration:绝对值。单位=steps/sec/sec。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/76390.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何提取视频中的音频?几个步骤轻松提取

在现今社交媒体的风靡下&#xff0c;许多人都会使用手机录制视频来记录生活中的美好瞬间。有时候&#xff0c;我们也会想要提取视频中的音频&#xff0c;例如将自己的演讲录音分发给听众。本文将会介绍如何在手机上提取视频中的音频以及需要注意的事项。 使用应用程序 首先&am…

Linux命令200例:write用于向特定用户或特定终端发送信息

&#x1f3c6;作者简介&#xff0c;黑夜开发者&#xff0c;CSDN领军人物&#xff0c;全栈领域优质创作者✌。CSDN专家博主&#xff0c;阿里云社区专家博主&#xff0c;2023年6月csdn上海赛道top4。 &#x1f3c6;数年电商行业从业经验&#xff0c;历任核心研发工程师&#xff0…

Android高德地图截屏功能(可包含自定义控件)

一、不包含自定义控件 地图 SDK 支持对当前屏幕显示区域进行截屏&#xff0c;可以对地图、覆盖物&#xff08;包含信息窗口&#xff09;、Logo进行截取屏幕&#xff0c;这其中不包括地图控件、Toast窗口。 详细示例如下&#xff1a; // 对地图进行截屏aMap!!.getMapScreenSho…

正交试验设计法

正交实验设计 一、什么是正交试验设计法&#xff1f; 是一种成对测试交互的系统的统计方法。它提供了一种能对所有变量对的组合进行典型覆盖&#xff08;均匀分布&#xff09;的方法。 可以从大量的试验点中挑出适量的、有代表性的点&#xff0c;利用“正交表”&#xff0c;…

Python之数据库(MYSQL)连接

一&#xff09;数据库SQL语言基础 MySQL是一个关系型数据库管理系统&#xff0c;由瑞典MySQL AB 公司开发&#xff0c;目前属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一&#xff0c;在 WEB 应用方面&#xff0c;MySQL是最好的 RDBMS (Relational Database…

PYTHON链家租房数据分析:岭回归、LASSO、随机森林、XGBOOST、KERAS神经网络、KMEANS聚类、地理可视化...

全文下载链接:http://tecdat.cn/?p29480 作者&#xff1a;Xingsheng Yang 1 利用 python 爬取链家网公开的租房数据&#xff1b; 2 对租房信息进行分析&#xff0c;主要对房租相关特征进行分析&#xff0c;并搭建模型用于预测房租&#xff08;点击文末“阅读原文”获取完整代码…

【基础计算机网络1】认识计算机网络体系结构,了解计算机网络的大致模型(下)

前言 在上一篇我们主要介绍了有关计算机网络概述的内容&#xff0c;下面这一篇我们将来介绍有关计算机网络体系结构与参考模型的内容。这一篇博客紧紧联系上一篇博客。 这一篇博客主要内容是&#xff1a;计算机网络体系结构与参考模型&#xff0c;主要是计算机网络分层结构、协…

Swift如何使用Vision来识别获取图片中的文字(OCR),通过SwiftUI视图和终端命令行,以及一系列注意事项

在过去的一年里&#xff0c;我发现苹果系统中的“文字搜图片”功能非常好用&#xff0c;这个功能不光 iPhone/iPad&#xff0c;Mac 也有&#xff0c;找一些图片真的很好用。但是遇到了一个问题&#xff1a;这个功能需要一段时间才能找到新的图片&#xff0c;而且没法手动刷新&a…

STM32-HAL库07-软件SPI驱动0.96寸OLED

STM32-HAL库07-软件SPI驱动0.96寸OLED 一、所用材料&#xff1a; STM32VGT6自制控制板 STM32CUBEMX&#xff08;HAL库软件&#xff09; MDK5 二、所学内容&#xff1a; 通过HAL库配置四个GPIO输出口&#xff0c;对其进行软件模拟SPI发送规则&#xff0c;进而驱动OLED进行数…

火山引擎边缘云助力智能科技赋予生活更多新意

当下&#xff0c;先进的科学技术使得我们的日常生活变得快捷、舒适。大到上百层智能大厦、高端公共场所、社会智能基础设施&#xff0c;小到智能家居监控、指纹密码锁等&#xff0c;在这个充满想象力的时代&#xff0c;科技以更加智能化的方式改变和守护我们的生活。 引入智能…

IO和进程day05(进程与线程)

今日任务 1.代码 #include <stdio.h> #include <string.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <sys/wait.h> #include <pthread.h>…

基于springboot2+mybatis-plus+jsp增删改查

概述 编写简单增删改查&#xff0c;理解之后可以自己试着扩展&#xff0c;相信你也可以&#xff0c;加油&#xff0c;我自己懂了的用注释记在下面方便理解 详细 一、需求&#xff08;要做什么&#xff09; 基于现今最流行的技术实现增删改查demo&#xff0c; 便于初学者上手…

2020年12月 C/C++(一级)真题解析#中国电子学会#全国青少年软件编程等级考试

C/C编程&#xff08;1~8级&#xff09;全部真题・点这里 第1题&#xff1a;字符三角形 描述 给定一个字符&#xff0c;用它构造一个底边长5个字符&#xff0c;高3个字符的等腰字符三角形。 输入 输入只有一行&#xff0c; 包含一个字符。 输出 该字符构成的等腰三角形&#xff…

nuxt3项目使用pdfjs-dist预览pdf

使用的包的源代码是 pdfjs - npm 但是我们实际上项目中使用的是pdfjs打包后的dist文件&#xff0c;也就是pdfjs-dist - npm 所以我们需要使用这个命令 npm i pdfjs-dist 我们可以克隆pdfjs这个包来看源代码&#xff0c;里面有使用的例子&#xff0c;也可以根据源代码自己打…

ClickHouse进阶(十三):Clickhouse数据字典-3-文件数据源及Mysql数据源

进入正文前&#xff0c;感谢宝子们订阅专题、点赞、评论、收藏&#xff01;关注IT贫道&#xff0c;获取高质量博客内容&#xff01; &#x1f3e1;个人主页&#xff1a;含各种IT体系技术,IT贫道_大数据OLAP体系技术栈,Apache Doris,Kerberos安全认证-CSDN博客 &#x1f4cc;订阅…

鸿蒙应用程序入口UIAbility详解

一、UIAbility概述 UIAbility是一种包含用户界面的应用组件&#xff0c;主要用于和用户进行交互。UIAbility也是系统调度的单元&#xff0c;为应用提供窗口在其中绘制界面。每一个UIAbility实例&#xff0c;都对应于一个最近任务列表中的任务。一个应用可以有一个UIAbility&am…

LVS + Keepalived群集

文章目录 1. Keepalived工具概述1.1 什么是Keepalived1.2 工作原理1.3 Keepailved实现原理1.4 Keepalived体系主要模块及其作用1.5 keepalived的抢占与非抢占模式 2. 脑裂现象 &#xff08;拓展&#xff09;2.1 什么是脑裂2.2 脑裂的产生原因2.3 如何解决脑裂2.4 如何预防脑裂 …

介绍PHP

PHP是一种流行的服务器端编程语言&#xff0c;用于开发Web应用程序。它是一种开源的编程语言&#xff0c;具有易学易用的语法和强大的功能。PHP支持在服务器上运行的动态网页和Web应用程序的快速开发。 PHP可以与HTML标记语言结合使用&#xff0c;从而能够生成动态的Web页面&a…

关于前端就业前景的一点看法

一、前言 最近&#xff0c;很多人在知乎上鼓吹前端未来会没掉的概念。在此我想说这个说法并不真实&#xff0c;而是一种极端的观点。 事实上&#xff0c;前端开发在当今的互联网行业中扮演着至关重要的角色&#xff0c;它是构建 Web 应用程序所必需的一部分&#xff0c;能够实现…

小白学go基础04-命名惯例对标识符进行命名

计算机科学中只有两件难事&#xff1a;缓存失效和命名。 命名是编程语言的要求&#xff0c;但是好的命名却是为了提高程序的可读性和可维护性。好的命名是什么样子的呢&#xff1f;Go语言的贡献者和布道师Dave Cheney给出了一个说法&#xff1a;“一个好笑话&#xff0c;如果你…