You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用pythonnet调用EPOS4的VcsGetPositionIs/VcsGetVelocityIs始终返回0求助

处理Maxon EPOS4控制器pythonnet引用参数问题

问题背景

使用Python+pythonnet读取Maxon EPOS4电机控制器的位置/速度时,初始化和控制电机正常,但调用VcsGetPositionIs/VcsGetVelocityIs方法始终返回0或参数类型错误,无法获取实际读数。

环境与依赖

  • 系统:Windows 10 + VS Code + Python 3.13
  • 依赖:pythonnet(最新版)
  • .NET库:EposCmd.Net.dll、EposCmd64.dll(放置于程序目录)
  • 导入代码:
import time
import os, sys
import ctypes
import clr
from EposCmd.Net.VcsWrapper import Device

尝试的读取代码(失败)

def read_current_positions(keyHandle, node_ids):
    positions = {}
    
    for node_id in node_ids:
        try:
            positionIs = 0
            errorCode = 0
            
            result = Device.VcsGetPositionIs(
                keyHandle,
                node_id,
                positionIs,
                errorCode
            )
            
            if result:
                positions[node_id] = positionIs
            else:
                positions[node_id] = f"Error reading position (ErrorCode: {errorCode})"
                
        except Exception as e:
            positions[node_id] = f"Failed to read position: {str(e)}"
            
    return positions

已尝试的参数处理方式(均无效)

  • 直接用Python原生int:返回0
  • 使用ctypes类型:
    positionIs = ctypes.c_long(0)
    errorCode = ctypes.c_ulong(0)
    
    错误:No method matches given arguments for Device.VcsGetPositionIs: (<class 'int'>, <class 'int'>, <class 'ctypes.c_long'>, <class 'ctypes.c_ulong'>)
  • 使用System.Int32/UInt32数组类型(未实例化):
    positionIs = System.Int32[]
    errorCode = System.UInt32[]
    
    错误:No method matches given arguments for Device.VcsGetPositionIs: (<class 'int'>, <class 'int'>, <class 'System.Int32[]'>, <class 'System.UInt32[]'>)
  • 尝试clr.Reference:
    positionIs = clr.Reference[int](0)
    
    错误:module 'clr' has no attribute 'Reference'

目标方法签名(EPOS文档)

bool VcsGetPositionIs(int KeyHandle, int NodeId, ref int PositionIs, ref uint ErrorCode)

解决方案

pythonnet 3.x及以上版本已移除clr.Reference,处理.NET的ref参数需使用以下两种正确方式:

方式1:使用.NET值类型的__ref__()方法

  1. 先导入System模块:
import System
  1. 修改读取函数:
def read_current_positions(keyHandle, node_ids):
    positions = {}
    
    for node_id in node_ids:
        try:
            # 初始化.NET原生值类型实例
            positionIs = System.Int32(0)
            errorCode = System.UInt32(0)
            
            # 调用方法时传递引用(使用__ref__())
            result = Device.VcsGetPositionIs(
                keyHandle,
                node_id,
                positionIs.__ref__(),
                errorCode.__ref__()
            )
            
            if result:
                positions[node_id] = int(positionIs)
            else:
                positions[node_id] = f"Error reading position (ErrorCode: {int(errorCode)})"
                
        except Exception as e:
            positions[node_id] = f"Failed to read position: {str(e)}"
            
    return positions

方式2:用单元素.NET数组模拟引用传递

数组属于引用类型,方法内部修改数组元素会被外部感知:

import System

def read_current_positions(keyHandle, node_ids):
    positions = {}
    
    for node_id in node_ids:
        try:
            # 初始化长度为1的.NET数组
            positionIs = System.Int32[1](0)
            errorCode = System.UInt32[1](0)
            
            # 直接传递数组作为ref参数
            result = Device.VcsGetPositionIs(
                keyHandle,
                node_id,
                positionIs,
                errorCode
            )
            
            if result:
                positions[node_id] = int(positionIs[0])
            else:
                positions[node_id] = f"Error reading position (ErrorCode: {int(errorCode[0])})"
                
        except Exception as e:
            positions[node_id] = f"Failed to read position: {str(e)}"
            
    return positions

关键注意点

  • 必须使用.NET原生的System.Int32/System.UInt32类型,不能用Python原生int或ctypes类型,否则会出现参数不匹配错误。
  • 调用方法后,将.NET类型实例的值转换为Python int即可正常使用。

内容的提问来源于stack exchange,提问作者user30706632

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 22:34:51