首页 > 其他分享 >struct.error: 'H' format requires 0 <= number <= 65535

struct.error: 'H' format requires 0 <= number <= 65535

时间:2023-10-12 11:37:06浏览次数:35  
标签:struct format register number coord encoder part fraction integer

全部代码如下:

from pymodbus.client import ModbusTcpClient

# 避坑:write_registers和write_register函数差一个s。多一个s的参数用整型列表,没有的只能用整型

def split_float_to_integer_and_fraction_parts(number):
    """
    将浮点数拆分为整数部分和小数部分的函数
    """
    integer_part = int(number)
    fraction_part = int((number - integer_part) * 10000)  # 将小数部分转换为整数
    print(integer_part, "和", fraction_part)
    # 将负值转换为无符号整数
    # 将负值转换为无符号整数
    if number < 0:
        integer_part = 65536 + integer_part
        fraction_part = 65536 + fraction_part
    return integer_part, fraction_part

def send_coordinates_to_robot(coordinates, encoder_value, host_ip='192.168.0.11', host_port=502):
    """
    将坐标发送给机器人的函数
    """
    # 分解编码器值
    result = None
    # print(encoder_value,"encoder_value")
    h4_encoder_integer_part = abs(int(encoder_value / 10000))
    l4_encoder_integer_part = abs(int(encoder_value - h4_encoder_integer_part * 10000))
    encoder_fraction_part = abs(int((encoder_value - int(encoder_value)) * 1000))

    # 创建并连接到Modbus服务器
    client = ModbusTcpClient(host_ip, port=host_port)
    connection = client.connect()
    if connection:
        result = "成功连接到Modbus服务器。"
    else:
        return "无法连接到Modbus服务器。"

    # 准备用于保存 坐标 -> 寄存器值 的列表
    register_coord = []
    # 准备用于保存 传送带编码值 -> 寄存器值 的列表
    register_encoder = []
    # 固定结束位
    end = 1

    # 依次写入坐标寄存器和工件属性寄存器
    # x->(102.103) y->(104.105) z->(106.107) c->(108.109)
    for i, (key, coordinate) in enumerate(coordinates.items()):
        # 跳过"AREA"和"ID"字段
        if key not in ["x", "y", "z", "c", "ATTR"]:
            continue
        # 坐标
        if key in ["x", "y", "z", "c"]:
            coord_integer_part, coord_fraction_part = split_float_to_integer_and_fraction_parts(coordinate)
            register_coord.extend([coord_integer_part, coord_fraction_part])
        # 传送带不在寄存器连续区间
        # 物料属性
        if key == "ATTR":
            register_coord.append(coordinate)

    # 写入编码器值寄存器:整数高4位,整数低4位,小数4位
    register_encoder.extend([h4_encoder_integer_part, l4_encoder_integer_part, encoder_fraction_part])
    print(register_coord)
    print(register_encoder)
    # 从102开始写到109,坐标+工件属性
    response1 = client.write_registers(102, register_coord, slave=1)
    # 从124开始写到126,编码器值
    response2 = client.write_registers(124, register_encoder, slave=1)
    # 在111写入结束位1
    response3 = client.write_register(111, end, slave=1)

    if response1.isError() or response2.isError():
        result += "写入寄存器失败"
    elif response3.isError():
        result += "写入结束位失败"
    else:
        result += "成功写入寄存器,并发送物料信息至机器人"

    # 关闭连接
    client.close()

    # 返回一条消息,表示操作已完成
    return result

send_coordinates_to_robot({
    'x': -2215,
    'y': -5,
    'z': -812.66,
    'c': 23.4038,
    'ATTR': 2,
}, 0)

调试:

输出:

为什么我小数大于零还进入了if分支???
我以为是Python有-0的问题,给我惊呆了,居然有负0。

x = -0
print(x)
if x == 0:
    print("x==0,加1后:", x + 1)
elif x < 0:
    print("x<0,加1后:", x + 1)
elif x > 0:
    print("x>0,加1后:", x + 1)

说明不是负0的问题。
然后我最后才发现,用来判断的数不是我分解后的数。
这是原来的:

    if number < 0:
        integer_part = 65536 + integer_part
        fraction_part = 65536 + fraction_part

修改后,应该分别判断他们是不是小于0

# 将负值转换为无符号整数
    if integer_part < 0:
        print("加之前:", fraction_part)
        integer_part = 65536 + integer_part
    if fraction_part < 0:
        fraction_part = 65536 + fraction_part

这是上一个人给我遗留的代码,真的难找。

标签:struct,format,register,number,coord,encoder,part,fraction,integer
From: https://www.cnblogs.com/x9nu/p/17759091.html

相关文章

  • cmakelist文件format
    这里主要是希望在vscode中编写CMakeList.txt过程中,对[[cmake]]语言进行format处理。首先在vscode中安装cmake-format插件cmake-format-VisualStudioMarketplace然后需要安装cmake-format.exe程序。这里需要使用[[Python]]进行安装:pipinstallcmake_forma......
  • 使用mapstruct做对象属性转换
    MapStruct是一个Java注解处理器,它可以自动生成类型安全的JavaBean映射代码。MapStruct的主要目的是简化JavaBean之间的映射,它通过注解来指定JavaBean之间的映射规则,然后自动生成映射代码。在MapStruct中,有几个常用的注解:@Mapper:用于指定一个JavaBean映射器接口,该接口定义......
  • [CF1870F] Lazy Numbers
    LazyNumbers我觉得本题难度在于银剑的构造......我们把k进制下的数去掉前导零放在Trie树上,并且越高位的深度越小,这样我们看出某个节点的dfs序就是排名,称排名减数值为va。我们需要求va=0的点数。不难发现某一深度从左往右的va单调不降,所以可以二分求出每层的点......
  • Codeforces Round 707 (Div. 2, based on Moscow Open Olympiad in Informatics) B. N
    按以下\(n\)次操作制作蛋糕。叠上第\(i\)块面包,然后浇上\(a_i\)单位的奶油。可以使当前往下\(a_i\)块面包沾上奶油。输出空格隔开的\(n\)个数,第\(i\)个的\(0/1\)代表第\(i\)块面包是否沾有奶油。比较显然的思路可以进行差分修改。view1#include<bits/std......
  • MySQL 低版本 解决row_number()over()无法使用的方法
    MySQL8以上版本支持了很多的窗口函数,但是低版本的可能也需要用到row_number()over()selecta.u_name,a.class,a.score,if((@class=null)or(@class=a.class),@rownum:=@rownum+1,@rownum:=1)rn,#没有并列情况if((@class=......
  • Math、System、Runtime //BigDecimal、Date、SimpleDaateFormat、Calendar
    1、Math =======================================================================================BigDecimal 1、构造器publicBigDecimal(Stringval)publicclassBigDecimalDemo01{publicstaticvoidmain(String[]args){//目标:掌握BigDecimal的......
  • C#教程 - 元组与解构(Tuples and Deconstruction )
    C#教程-元组与解构(TuplesandDeconstruction) 更新记录转载请注明出处:2022年9月24日发布。2022年9月10日从笔记迁移到博客。元组(tuples)说明#注意:C#7.0可用注意:元组不可以声明为静态类型作用:元组常用于传递和返回多个值;匿名类型可以做的,Tuples基本都可以完成元组是......
  • EDI data format
    http://www.edidev.com/XMLvsEDI.htmlEDIvs.XML  EDIToolforDevelopersWhatisEDI?EDIorElectronicDataInterchangeistheexchangeofinformationinastandardformatbetweencomputerswithoutanyhumanintermediary.HasEDIbecomeobsolete?Farfrom......
  • Rethinking Point Cloud Registration as Masking and Reconstruction论文阅读
    RethinkingPointCloudRegistrationasMaskingandReconstruction2023ICCV*GuangyanChen,MeilingWang,LiYuan,YiYang,YufengYue*;ProceedingsoftheIEEE/CVFInternationalConferenceonComputerVision(ICCV),2023,pp.17717-17727paper:Rethin......
  • mybatis出现错误 java lang NumberFormatException:For input string:A1
    使用mybatis,当使用map传参并且在iftest判断时使用map中所传的参数时,可能会产生如题的报错,具体报错信息见下图:分析这个错误,自己调试也找过度娘,“坚信”自己代码并没问题,但是问题始终无法解决。最后在一个帖子看到说iftest判断时,传入的参数跟匹配的值类型必须一致,于是调整了自己代......