xml转csv__fault

本文介绍了一个使用Python进行XML文件解析并转换为CSV格式的过程。作者尝试了多种方法,包括lxml和xml.dom.minidom等库,但在输出中文内容方面遇到了困难。文中详细记录了所使用的代码片段及遇到的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#encoding=utf-8
import csv
import lxml.etree
from lxml import etree
from io import StringIO
import xml.etree.ElementTree as et



header=('type','ID','Text','PublishData','Code','Keyword')
with open('/home/henson/Desktop/001/output.csv', 'w',encoding='utf-16') as outfile:
    writer = csv.writer(outfile)
    writer.writerow((header))
    #tree = etree.parse("/home/henson/Desktop/001/666.xml")
  #  root = lxml.etree.fromstring(infile)
    #parser = etree.XMLParser(ns_clean=True)
    #tree = etree.parse(("/home/henson/Desktop/001/666.xml"), parser)
    #a=etree.tostring(tree,encoding='utf-8')
    infile='/home/henson/Desktop/001/666.xml'
    tree=et.ElementTree(file=infile)
    root=tree.getroot()
    for PeriodicalPaper in root:
        #print(PeriodicalPaper)
        for Text in PeriodicalPaper:
            Text=Text.findall('Keyword')
            #Keyword=Text.findall('Keyword')
            print(Text)
            row=Text
        writer.writerow(row)
import csv
import lxml
from bs4 import BeautifulSoup
soup=BeautifulSoup('/home/henson/Desktop/001/666.xml','lxml')
header=('type','ID','Text','PublishData','Code','Keyword')
with open('output.csv', 'w',encoding='utf-8') as f:
    writer = csv.writer(f)
    writer.writerow((header))
    #xmlDataFileHandler = open(infile, 'r+')
    #xmlstring = xmlDataFileHandler.read().encode()
    #print(xmlstring)
    #root = etree.fromstring(xmlstring)
    #print(etree.tostring(root))
    #for PeriodicalPaper in root:
     #   print(PeriodicalPaper.tag)
     #   keyword = PeriodicalPaper.find('Keyword')
      #  print(keyword)
       # writer.writerow(keyword)
    print(soup.Text)
from xml.dom.minidom import parseString

def parseXML(fpath):
    tupleList = []
    content = open(r'/home/henson/Desktop/001/666.xml',"r+").read()
    try:
        xmldoc = parseString(content)
    except:
        print ("ill formed xml file")
    DocumentList = xmldoc.getElementsByTagName('PeriodicalPaper')
    for doc in DocumentList:
        Text = doc.getElementsByTagName('Text')
        ID = doc.getElementsByTagName('ID')
        Keyword = doc.getElementsByTagName('Keywords')
        tuple = [Text,ID,Keyword]
        tupleList.append(tuple)
    return tupleList

if __name__ == "__main__":
    ls = parseXML(r"/home/henson/Desktop/001/666.xml")
    for em in ls:
        for e in em:
            print (e[0].firstChild.data)

xml转csv,研究了一天都不知道怎么弄,用了lxml解析,但是还是无法输出中文,只有[][][][]用getElementsByTagName来获取,但不是我要的格式.
感觉就是很简单,但又不是那么简单,废了一天也没搞出来,比我预期的还要多时间,挫败感十足。

下面是我的Linuxcnc控制伺服电机的hal文件,怎么通过引脚的方式让OPenplc可以和Linuxcnc交换数据 loadrt [KINS]KINEMATICS loadrt [EMCMOT]EMCMOT servo_period_nsec=[EMCMOT]SERVO_PERIOD num_joints=[KINS]JOINTS loadusr -W lcec_conf ethercat-conf.xml loadrt lcec loadrt cia402 count=4 addf motion-command-handler servo-thread addf motion-controller servo-thread addf lcec.read-all servo-thread addf lcec.write-all servo-thread addf cia402.0.read-all servo-thread addf cia402.0.write-all servo-thread addf cia402.1.read-all servo-thread addf cia402.1.write-all servo-thread addf cia402.2.read-all servo-thread addf cia402.2.write-all servo-thread addf cia402.3.read-all servo-thread addf cia402.3.write-all servo-thread #config # 模式 1csp 0csv setp cia402.0.csp-mode 1 setp cia402.0.pos-scale 1677721.6 setp cia402.1.csp-mode 1 setp cia402.1.pos-scale 1677721.6 setp cia402.2.csp-mode 1 setp cia402.2.pos-scale 1677721.6 setp cia402.3.csp-mode 1 setp cia402.3.pos-scale 1677721.6 #连接第一台伺服(轴0) #from servo(ethercat) to cia402 net x-statusword lcec.0.0.cia-statusword => cia402.0.statusword net x-opmode-display lcec.0.0.opmode-display => cia402.0.opmode-display net x-drv-act-pos lcec.0.0.actual-position => cia402.0.drv-actual-position net x-drv-act-velo lcec.0.0.actual-velocity => cia402.0.drv-actual-velocity #from cia402 to servo(ethercat) net x-controlword cia402.0.controlword => lcec.0.0.cia-controlword net x-modes-of-operation cia402.0.opmode => lcec.0.0.opmode net x-drv-target-pos cia402.0.drv-target-position => lcec.0.0.target-position net x-drv-target-velo cia402.0.drv-target-velocity => lcec.0.0.target-velocity #连接第二台伺服(轴1) net y-statusword lcec.0.1.cia-statusword => cia402.1.statusword net y-opmode-display lcec.0.1.opmode-display => cia402.1.opmode-display net y-drv-act-pos lcec.0.1.actual-position => cia402.1.drv-actual-position net y-drv-act-velo lcec.0.1.actual-velocity => cia402.1.drv-actual-velocity net y-controlword cia402.1.controlword => lcec.0.1.cia-controlword net y-modes-of-op cia402.1.opmode => lcec.0.1.opmode net y-drv-target-pos cia402.1.drv-target-position => lcec.0.1.target-position net y-drv-target-velo cia402.1.drv-target-velocity => lcec.0.1.target-velocity #连接第三台伺服(轴2) net z-statusword lcec.0.2.cia-statusword => cia402.2.statusword net z-opmode-display lcec.0.2.opmode-display => cia402.2.opmode-display net z-drv-act-pos lcec.0.2.actual-position => cia402.2.drv-actual-position net z-drv-act-velo lcec.0.2.actual-velocity => cia402.2.drv-actual-velocity net z-controlword cia402.2.controlword => lcec.0.2.cia-controlword net z-modes-of-op cia402.2.opmode => lcec.0.2.opmode net z-drv-target-pos cia402.2.drv-target-position => lcec.0.2.target-position net z-drv-target-velo cia402.2.drv-target-velocity => lcec.0.2.target-velocity #连接第四台伺服(轴3) net c-statusword lcec.0.3.cia-statusword => cia402.3.statusword net c-opmode-display lcec.0.3.opmode-display => cia402.3.opmode-display net c-drv-act-pos lcec.0.3.actual-position => cia402.3.drv-actual-position net c-drv-act-velo lcec.0.3.actual-velocity => cia402.3.drv-actual-velocity net c-controlword cia402.3.controlword => lcec.0.3.cia-controlword net c-modes-of-op cia402.3.opmode => lcec.0.3.opmode net c-drv-target-pos cia402.3.drv-target-position => lcec.0.3.target-position net c-drv-target-velo cia402.3.drv-target-velocity => lcec.0.3.target-velocity #from motion to cia net x-enable <= joint.0.amp-enable-out => cia402.0.enable net x-amp-fault => joint.0.amp-fault-in <= cia402.0.drv-fault net x-pos-cmd <= joint.0.motor-pos-cmd => cia402.0.pos-cmd net x-pos-fb => joint.0.motor-pos-fb <= cia402.0.pos-fb net y-enable <= joint.1.amp-enable-out => cia402.1.enable net y-amp-fault => joint.1.amp-fault-in <= cia402.1.drv-fault net y-pos-cmd <= joint.1.motor-pos-cmd => cia402.1.pos-cmd net y-pos-fb => joint.1.motor-pos-fb <= cia402.1.pos-fb net z-enable <= joint.2.amp-enable-out => cia402.2.enable net z-amp-fault => joint.2.amp-fault-in <= cia402.2.drv-fault net z-pos-cmd <= joint.2.motor-pos-cmd => cia402.2.pos-cmd net z-pos-fb => joint.2.motor-pos-fb <= cia402.2.pos-fb net c-enable <= joint.3.amp-enable-out => cia402.3.enable net c-amp-fault => joint.3.amp-fault-in <= cia402.3.drv-fault net c-pos-cmd <= joint.3.motor-pos-cmd => cia402.3.pos-cmd net c-pos-fb => joint.3.motor-pos-fb <= cia402.3.pos-fb setp iocontrol.0.emc-enable-in 1
06-21
<think>我们正在讨论如何通过引脚方式实现OpenPLC与LinuxCNC之间的实时数据交换,特别是控制伺服电机的场景。用户明确要求配置LinuxCNC的HAL文件来实现这一目标。关键点:1.使用HAL(硬件抽象层)引脚进行数据交换是LinuxCNC的核心机制。2.OpenPLC需要能够读写这些引脚,从而与LinuxCNC交换控制伺服电机所需的数据(如位置、速度、使能信号等)。3.配置步骤包括:创建HAL引脚、连接这些引脚到LinuxCNC内部组件(如运动控制器)、以及设置OpenPLC访问这些引脚。具体步骤:步骤1:在LinuxCNC中定义HAL引脚在HAL文件中(通常是`.hal`文件),我们需要定义用于与OpenPLC通信的引脚。这些引脚可以是输入或输出类型,例如:-输出引脚(LinuxCNC->OpenPLC):当前实际位置、状态标志等。-输入引脚(OpenPLC->LinuxCNC):目标位置、速度命令、使能信号等。示例HAL引脚定义(添加到自定义的HAL文件,比如`custom.hal`):```hal#创建伺服电机控制相关的引脚#输入引脚(由OpenPLC写入,LinuxCNC读取)netservo-enable<=parport.0.pin-09-out#使能信号netservo-vel-cmd<=parport.0.pin-10-out#速度命令(假设使用并行端口)netservo-pos-cmd<=parport.0.pin-11-out#位置命令#输出引脚(由LinuxCNC写入,OpenPLC读取)netservo-actual-pos=>parport.0.pin-12-in#实际位置netservo-fault=>parport.0.pin-13-in#故障状态```注意:这里假设使用并行端口(parport)进行连接。实际上,OpenPLC和LinuxCNC可能运行在同一台机器上,我们可以使用虚拟引脚(如HAL内存引脚)来实现更高效的通信。步骤2:使用HAL内存引脚(推荐)为了避免物理硬件的限制,我们可以使用HAL内存引脚(`halmem`),它允许不同进程通过共享内存访问HAL引脚。首先,在LinuxCNC的HAL配置中加载`halmem`模块(通常在`custom.hal`文件中):```halloadrthalmemsize=32768#分配32KB共享内存```然后,定义内存引脚:```hal#创建内存引脚addfhalmem.readservo-threadaddfhalmem.writeservo-thread#定义输入引脚(OpenPLC写入,LinuxCNC读取)netservo-enable<=halmem.0.in.00netservo-vel-cmd<=halmem.0.in.01netservo-pos-cmd<=halmem.0.in.02#定义输出引脚(LinuxCNC写入,OpenPLC读取)netservo-actual-pos=>halmem.0.out.00netservo-fault=>halmem.0.out.01```步骤3:将HAL引脚连接到运动控制器在LinuxCNC中,伺服电机的控制通常通过PID组件实现。我们需要将上述引脚连接到PID组件和电机编码器反馈等。示例连接(在HAL文件中):```hal#连接位置命令到PID的设定点netservo-pos-cmd=>pid.0.setpoint#连接实际位置(来自编码器反馈)netencoder-feedback=>pid.0.feedback#连接速度命令到PID的输出限制(可选)setppid.0.maxoutputservo-vel-cmd#使能信号连接到PID和电机驱动netservo-enable=>pid.0.enablenetservo-enable=>motor-drive.0.enable```步骤4:配置OpenPLC访问HAL引脚OpenPLC支持通过自定义C代码或Python脚本访问HAL引脚。我们可以使用OpenPLC的“C模块”功能或“Python脚本”功能来实现。方法A:使用OpenPLC的Python脚本功能(推荐)-在OpenPLC编辑器中添加一个Python脚本(作为程序组织单元POU)。-使用python-hal库(需要安装)来访问HAL内存引脚。示例Python脚本(在OpenPLC中周期性执行):```pythonimporthal#初始化HAL组件h=hal.component("openplc")#创建输入引脚(对应HAL内存中的输出引脚,即LinuxCNC写入的引脚)actual_pos=h.newpin("actual-pos",hal.HAL_FLOAT,hal.HAL_IN)fault_flag=h.newpin("fault",hal.HAL_BIT,hal.HAL_IN)#创建输出引脚(对应HAL内存中的输入引脚,即OpenPLC写入的引脚)enable_out=h.newpin("enable",hal.HAL_BIT,hal.HAL_OUT)vel_cmd_out=h.newpin("vel-cmd",hal.HAL_FLOAT,hal.HAL_OUT)pos_cmd_out=h.newpin("pos-cmd",hal.HAL_FLOAT,hal.HAL_OUT)h.ready()#激活组件#在循环中更新引脚值(OpenPLC的每个周期执行)whileTrue:#读取实际位置和故障状态(从LinuxCNC)current_pos=actual_pos.get()is_fault=fault_flag.get()#根据控制逻辑计算新的命令(这里仅示例)#例如:如果没有故障,则使能电机,并设置位置命令ifnotis_fault:enable_out.set(True)pos_cmd_out.set(100.0)#目标位置100单位vel_cmd_out.set(10.0)#速度命令10单位/秒else:enable_out.set(False)#等待下一个周期(OpenPLC会自动管理周期)```方法B:使用OpenPLC的C模块-编写一个C代码模块,使用LinuxCNC的HAL库(libhal.so)直接访问内存引脚。-在OpenPLC的“C模块”部分添加此代码。步骤5:测试与验证-启动LinuxCNC并加载配置的HAL文件。-启动OpenPLC并加载包含上述脚本的项目。-使用HAL命令行工具(如`halcmd`)监视引脚状态,确保数据正确传递。注意事项:-实时性:确保LinuxCNC和OpenPLC都运行在具有实时内核的Linux系统上(如PREEMPT_RT)。-引脚命名:在HAL文件和OpenPLC脚本中使用的引脚名称必须一致。-数据类型:确保引脚数据类型匹配(如HAL_FLOAT对应浮点数,HAL_BIT对应布尔值)。通过以上步骤,我们可以实现OpenPLC通过HAL引脚与LinuxCNC交换数据,进而控制伺服电机。---###§§相关问题§§1.如何在LinuxCNC中配置PID控制器来控制伺服电机?2.如何安装和配置实时Linux内核以支持LinuxCNC和OpenPLC的实时需求?3.OpenPLC中如何使用Python脚本访问硬件引脚?4.如何通过HAL命令行工具(halcmd)监控和调试HAL引脚?5.在LinuxCNC中,如何处理伺服电机的编码器反馈信号?</think>### 通过HAL引脚实现OpenPLC与LinuxCNC的伺服电机控制 在LinuxCNC中,硬件抽象层(HAL)是实现实时数据交换的核心机制。通过配置HAL引脚,OpenPLC可以直接与LinuxCNC交换数据来控制伺服电机。以下是具体配置步骤: #### 1. **HAL引脚配置基础** 在LinuxCNC的HAL文件中(通常为`.hal`文件),需要定义三类关键引脚: ```hal # 控制信号引脚 (OpenPLC → LinuxCNC) net servo-enable => motion.enable # 伺服使能信号 net servo-pos-cmd => motion.analog-out-00 # 位置指令值 net servo-vel-cmd => motion.analog-out-01 # 速度指令值 # 状态反馈引脚 (LinuxCNC → OpenPLC) net servo-actual-pos <= joint.0.feedback # 实际位置反馈 net servo-fault <= joint.0.fault # 故障状态 # 物理引脚映射 (连接到硬件接口) setp parport.0.pin-09-out servo-enable # 示例:并口引脚映射 net servo-pos-cmd => hm2_5i25.0.7i77.0.0.out # 示例:Mesa硬件卡 ``` #### 2. **伺服电机控制专用引脚** 在`custom.hal`中添加伺服控制专用组件: ```hal # 加载PID控制器组件 loadrt pid names=servo-pid addf servo-pid servo-thread # 引脚连接 (位置环控制示例) net pos-cmd => servo-pid.command # 位置指令 net actual-pos => servo-pid.feedback # 编码器反馈 net pid-output => motor-drive.0.speed-in # PID输出到驱动器 # 设置PID参数 setp servo-pid.Pgain 0.8 setp servo-pid.Igain 0.05 setp servo-pid.Dgain 0.01 ``` #### 3. **OpenPLC端的引脚映射** 在OpenPLC项目中创建对应的变量映射: ```c // 定义共享内存区域 #pragma pack(push, 1) typedef struct { uint8_t enable; // 对应 servo-enable float position_cmd; // 对应 servo-pos-cmd float velocity_cmd; // 对应 servo-vel-cmd float actual_pos; // 对应 servo-actual-pos bool fault; // 对应 servo-fault } HalData; #pragma pack(pop) // 实时更新函数 void updateHalPins() { HalData* hal = get_shared_memory(); hal->enable = %QX0.0; // 从PLC输入读取使能信号 hal->position_cmd = %MD100; // 从PLC寄存器读取位置指令 } ``` #### 4. **实时数据交换实现** 通过共享内存实现毫秒级同步: ```hal # LinuxCNC端加载halmem模块 loadrt halmem size=4096 addf halmem.read servo-thread addf halmem.write servo-thread # 绑定内存区域 net servo-enable <= halmem.0.in.00 net servo-actual-pos => halmem.0.out.04 ``` #### 5. **完整控制流程** 1. **控制流** OpenPLC计算运动指令 → 写入HAL内存 → LinuxCNC读取 → PID计算 → 驱动伺服电机 2. **反馈流** 编码器采样 → LinuxCNC位置处理 → 写入HAL内存 → OpenPLC读取 → 逻辑判断 ```mermaid graph LR A[OpenPLC] -- 位置/速度指令 --> B[HAL 内存引脚] B --> C[LinuxCNC PID控制器] C --> D[伺服驱动器] D --> E[伺服电机] E -- 编码器反馈 --> F[LinuxCNC] F --> B B -- 实际位置/状态 --> A ``` #### 6. **关键注意事项** 1. **实时性保障**: - 使用`PREEMPT_RT`内核补丁 - 设置HAL线程周期 ≤ 1ms: `setp halcmd.thread.period 1000000`(1ms周期) 2. **引脚数据类型匹配**: | PLC数据类型 | HAL引脚类型 | 示例应用 | |------------|------------|---------------| | BOOL | HAL_BIT | 使能信号 | | REAL | HAL_FLOAT | 位置指令 | | INT | HAL_S32 | 状态编码 | 3. **安全机制**: ```hal net estop => servo-pid.enable # 急停信号切断PID setp motor-drive.0.max-current 5.0 # 电流限制 ``` [^1]: LinuxCNC通过HAL实现硬件抽象和实时控制 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值