rambo 1 week ago
parent
commit
251a9e5f00
3 changed files with 456 additions and 0 deletions
  1. 252 0
      python/conifg_info.py
  2. 95 0
      python/mcu/DeviceControl.py
  3. 109 0
      python/utils/utils_func.py

+ 252 - 0
python/conifg_info.py

@@ -0,0 +1,252 @@
+# 地址、正负、类型(整数、浮点)、精度(0.01)、数据(6个字节)、是否只读
+CONFIG_METADATA = {}
+IS_TIPS = True
+
+
+def set_key_int(_key, _addr, _tips="", _type="int", _precision=0, _readonly=False):
+    if _key in CONFIG_METADATA:
+        print("{} is exist".format(_key))
+        raise 111
+    if IS_TIPS:
+        CONFIG_METADATA[_key] = {
+            "tips": _tips if IS_TIPS else "",
+            "addr": _addr,  # 寄存器起始地址(word 地址)
+            "type": _type,  # "int" 或 "float","bool"
+            "precision": 0,  # 精度(用于 UI 显示或缩放)0表示整数,1表示0.1,2表示0.02
+            "readonly": _readonly  # 是否只读 True为只读
+        }
+    else:
+        CONFIG_METADATA[_key] = {
+            "addr": _addr,  # 寄存器起始地址(word 地址)
+            "type": _type,  # "int" 或 "float","bool"
+            "precision": 0,  # 精度(用于 UI 显示或缩放)0表示整数,1表示0.1,2表示0.02
+            "readonly": _readonly  # 是否只读 True为只读
+        }
+
+
+def set_key_float(_key, _addr, _tips="", _type="float", _precision=1, _readonly=False):
+    if _key in CONFIG_METADATA:
+        print("{} is exist".format(_key))
+        raise 111
+    if IS_TIPS:
+        CONFIG_METADATA[_key] = {
+            "tips": _tips if IS_TIPS else "",
+            "addr": _addr,  # 寄存器起始地址(word 地址)
+            "type": _type,  # "int" 或 "float","bool"
+            "precision": _precision,  # 精度(用于 UI 显示或缩放)0表示整数,1表示0.1,2表示0.02
+            "readonly": _readonly  # 是否只读 True为只读
+        }
+    else:
+        CONFIG_METADATA[_key] = {
+            "addr": _addr,  # 寄存器起始地址(word 地址)
+            "type": _type,  # "int" 或 "float","bool"
+            "precision": _precision,  # 精度(用于 UI 显示或缩放)0表示整数,1表示0.1,2表示0.02
+            "readonly": _readonly  # 是否只读 True为只读
+        }
+
+
+test_key1 = 0.5
+set_key_float(_key="test_key1", _addr=1, _precision=2)
+test_key2 = 1
+set_key_int(_key="test_key2", _addr=2, _tips="测试-2", )
+
+# 升降机上次命令位置
+camera_high_motor_target_value = 0
+set_key_float(_key="camera_high_motor_target_value", _addr=3, _tips="升降机当前位置", _readonly=True)
+
+# 相机角度上次命令位置
+camera_steering_target_value = 0
+set_key_float(_key="camera_steering_target_value", _addr=4, _tips="相机角度上次命令位置", _readonly=True)
+
+# ---------------------50开始处理--------------------
+# 升降机当前实时位置
+camera_high_motor_current_value = 0
+set_key_float(_key="camera_high_motor_current_value", _addr=51, _tips="升降机当前实时位置", _readonly=True)
+
+# 相机角度当前实时位置
+camera_steering_current_value = 0
+set_key_float(_key="camera_steering_current_value", _addr=52, _tips="相机角度当前实时位置", _readonly=True)
+
+# 转盘角度当前实时位置
+turntable_steering_current_value = 0
+set_key_float(_key="turntable_steering_current_value", _addr=53, _tips="转盘角度当前实时位置", _readonly=True)
+
+# 转盘前后当前实时位置
+move_turntable_steering_current_value = 0
+set_key_float(_key="move_turntable_steering_current_value", _addr=54, _tips="转盘前后当前实时位置", _readonly=True)
+
+# 翻板通讯是否正常
+over_steering_is_online = 0
+set_key_int(_key="over_steering_is_online", _addr=55, _tips="翻板是否在线", _readonly=True)
+
+# --------------------------基础设置--------------从ID 100开始
+# 自动关机时间;单位秒
+auto_power_off_diff_time = 7200
+set_key_int(_key="auto_power_off_diff_time", _addr=101, _tips="自动关机时间单位秒", )
+
+# 自动去使能;单位秒 MOTOR_TO_DISABLE
+auto_motor_disable_diff_time = 180
+set_key_int(_key="auto_motor_disable_diff_time", _addr=102, _tips="自动去使能时间单位秒", )
+
+# 220V继电器是否转换方向
+relay_220v_is_change_dir = 0
+set_key_int(_key="relay_220v_is_change_dir", _addr=103, _tips="220V继电器是否转换方向", )
+
+# 伺服急停继电器是否转换方向
+relay_motor_stop_is_change_dir = 0
+set_key_int(_key="relay_motor_stop_is_change_dir", _addr=104, _tips="伺服急停继电器是否转换方向", )
+
+# 刹车继电器是否转换方向
+relay_brake_is_change_dir = 0
+set_key_int(_key="relay_brake_is_change_dir", _addr=105, _tips="刹车继电器是否转换方向", )
+
+# 增加升降的限位高度,单位mm
+camera_high_motor_max_height = 387
+set_key_int(_key="camera_high_motor_max_height", _addr=106, _tips="升降的限位高度", )
+
+# 是否检查设备是否在线
+is_check_motor_online = 1
+set_key_int(_key="is_check_motor_online", _addr=107, _tips="是否检查设备是否在线", )
+
+# 是否检查设备是否堵转
+is_check_motor_blocked = 1
+set_key_int(_key="is_check_motor_blocked", _addr=108, _tips="是否检查设备是否堵转", )
+
+# 是否完成设备自动参数设定
+has_been_set_motor_config = 0
+set_key_int(_key="has_been_set_motor_config", _addr=109, _tips="是否完成设备自动参数设定", )
+
+# 校准角度方向
+angle_diff_dir = 0
+set_key_int(_key="angle_diff_dir", _addr=110, _tips="校准角度方向", )
+
+# LED的默认亮度
+led_default_brightness = 60
+set_key_int(_key="led_default_brightness", _addr=111, _tips="LED的默认亮度", )
+
+# 是否自动关闭使能
+is_auto_motor_to_disable = 1
+set_key_int(_key="is_auto_motor_to_disable", _addr=112, _tips="是否自动关闭使能", )
+
+# 转盘转速比
+turntable_steering_angle_ratio = 35.6
+set_key_float(_key="turntable_steering_angle_ratio", _addr=113, _tips="转盘转速比", )
+
+# LED灯的数量
+led_count = 20
+set_key_int(_key="led_count", _addr=114, _tips="LED灯的数量", )
+
+# 转盘前后移动设备的初始化模式 1表示碰撞  0表示限位
+turntable_move_to_init_mode = 0
+set_key_int(_key="turntable_move_to_init_mode", _addr=115, _tips="转盘前后移动设备的初始化模式 1表示碰撞  0表示限位", )
+
+# 是否测试
+is_test = 0
+set_key_int(_key="is_test", _addr=116, _tips="is_test", )
+
+# 电机停止速度检测
+low_speed = 300
+set_key_int(_key="low_speed", _addr=117, _tips="电机停止速度检测", )
+
+# 自动发送基础信息
+is_auto_send_base_info = 0
+set_key_int(_key="is_auto_send_base_info", _addr=118, _tips="自动发送基础信息", )
+
+# 失去使能升降自动归零
+disable_camera_high_to_zero = 0
+set_key_int(_key="disable_camera_high_to_zero", _addr=119, _tips="失去使能升降自动归零", )
+
+# 前后移动电机初始化后距离
+front_rear_motor_init_distance = 0
+set_key_int(_key="front_rear_motor_init_distance", _addr=120, _tips="前后移动电机初始化后距离", )
+
+# 每秒自动检查电机是否停止
+auto_check_motor_stop = 0
+set_key_int(_key="auto_check_motor_stop", _addr=121, _tips="每秒自动检查电机是否停止", )
+
+# 前后移动电机是否存在
+turntable_move_is_exist = 1
+set_key_int(_key="turntable_move_is_exist", _addr=122, _tips="前后移动电机是否存在", )
+
+# -------------------------------------
+# 转盘偏移角度 单位1度
+turntable_steering_deviation = 0
+set_key_float(_key="turntable_steering_deviation", _addr=200, _tips="转盘偏移角度", )
+
+# 相机偏移角度 单位1度
+camera_steering_deviation = 0
+set_key_float(_key="camera_steering_deviation", _addr=201, _tips="相机偏移角度", )
+
+# 升降偏移距离mm
+camera_high_motor_deviation = 0
+set_key_int(_key="camera_high_motor_deviation", _addr=202, _tips="升降偏移距离mm", )
+
+# 翻板中位 单位1度
+overturn_steering_middle = 95
+set_key_float(_key="overturn_steering_middle", _addr=203, _tips="翻板中位 单位0.1度", )
+
+# 翻板高位 单位1度
+overturn_steering_high = 150
+set_key_float(_key="overturn_steering_high", _addr=204, _tips="翻板高位 单位0.1度", )
+
+# 翻板上升速度
+overturn_steering_up_speed = 2
+set_key_int(_key="overturn_steering_up_speed", _addr=205, _tips="翻板上升速度", )
+
+# 翻板下降速度
+overturn_steering_down_speed = 4
+set_key_int(_key="overturn_steering_down_speed", _addr=206, _tips="翻板下降速度", )
+
+# 是否完成初始化
+has_been_set = 0
+set_key_int(_key="has_been_set", _addr=207, _tips="是否完成初始化", _readonly=True)
+
+# 相机调焦功能支持
+camera_has_focal = 0
+set_key_int(_key="camera_has_focal", _addr=208, _tips="相机调焦功能支持", )
+
+# 相机最大焦段
+camera_max_focal = 55
+set_key_int(_key="camera_max_focal", _addr=209, _tips="相机最大焦段", )
+
+# 相机最小焦段
+camera_min_focal = 15
+set_key_int(_key="camera_min_focal", _addr=210, _tips="相机最小焦段", )
+
+# 相机焦段步进ratio
+camera_focal_ratio = 0.0
+set_key_float(_key="camera_focal_ratio", _addr=211, _tips="相机焦段步进ratio", )
+
+# 相机焦段步进自动归零
+camera_zoom_auto_to_zero = 1
+set_key_float(_key="camera_zoom_auto_to_zero", _addr=212, _tips="相机焦段步进自动归零", )
+
+# 相机焦段当前实时位置
+camera_zoom_motor_current_value = 0
+set_key_float(_key="camera_zoom_motor_current_value", _addr=213, _tips="相机焦段当前实时位置", _readonly=True)
+
+
+# =====================================================
+# 获取剩余内存
+get_memory = 0
+set_key_float(_key="get_memory", _addr=300, _tips="获取剩余内存", _readonly=True)
+
+# =====================================================
+
+# ===============调试用======================
+# 相机焦段功能设置
+camera_focal_set = 0
+set_key_float(_key="camera_focal_set", _addr=400, _tips="相机焦段功能设置", _readonly=True)
+
+
+# 生成一个以addr为key的字典
+CONFIG_METADATA_BY_ADDR = {}
+for key, meta in CONFIG_METADATA.items():
+    addr = meta["addr"]
+    if addr in CONFIG_METADATA_BY_ADDR:
+        print("{} 有重复".format(addr))
+        raise "11111111"
+    CONFIG_METADATA_BY_ADDR[addr] = key
+    # CONFIG_METADATA_BY_ADDR[addr]["key_name"] = key
+
+# print(CONFIG_METADATA)

+ 95 - 0
python/mcu/DeviceControl.py

@@ -5,6 +5,7 @@ import serial.tools.list_ports
 import time, json
 import time, json
 from .SerialIns import SerialIns
 from .SerialIns import SerialIns
 from utils.SingletonType import SingletonType
 from utils.SingletonType import SingletonType
+from utils.utils_func import dynamic_parameter_issuance_get
 from .BaseClass import BaseClass
 from .BaseClass import BaseClass
 from sockets import ConnectionManager
 from sockets import ConnectionManager
 from collections import defaultdict
 from collections import defaultdict
@@ -142,7 +143,101 @@ class DeviceControl(BaseClass, metaclass=SingletonType):
             92: self.get_from_mcu_move_respond_data,  # 获取MCU响应
             92: self.get_from_mcu_move_respond_data,  # 获取MCU响应
             100: self.print_mcu_error_data,  # 打印下位机的错误内容
             100: self.print_mcu_error_data,  # 打印下位机的错误内容
             255: self.print_mcu_noraml_data,  # 打印回执
             255: self.print_mcu_noraml_data,  # 打印回执
+            124: self.read_register_data_by_usb,  # 读取某个寄存器数据
+            125: self.write_register_data_by_usb,  # 写入某个寄存器数据
+            126: self.get_all_registers_list_by_usb,  # 获取所有寄存器
+            150: self.dynamic_parameter_issuance,  # 动态参数下发
         }
         }
+    def get_all_ids(self):
+        cmd = [124]
+        cmd.extend([0xff & 106 >> 8, 0xff & 106])
+        data = self.get_basic_info_mcu_without_async(data=cmd)
+        if not data:
+            return False
+        return_data = self.analysis_data(data[1:])
+        if return_data:
+            print(return_data)
+    # 获取异步数据
+    def analysis_data(self, _data):
+        _addr = _data[0] << 8 | _data[1]
+        if _addr not in CONFIG_METADATA_BY_ADDR:
+            return False
+        start = 2
+        _value = _data[start] << 40 | _data[start + 1] << 32 | _data[start + 2] << 24 | _data[start + 3] << 16 | _data[start + 4] << 8 | _data[start + 5]
+
+        start = start + 5
+        _read_only = True if _data[start + 1] == 1 else False  # 是否只读
+        _dir = 1 if _data[start + 2] == 1 else -1
+        _type = "int" if _data[start + 3] == 1 else "float"
+        _precision = _data[start + 4]
+
+        if _dir < 0:
+            _value = _value * _dir
+
+        if _type == "float":
+            if _precision > 0:
+                _round_x = _precision
+                _precision = _precision * -1
+                _value = _value * 10 ** _precision
+                _value = round(_value, _round_x)
+        else:
+            _value = int(_value)
+
+        return_data = {"addr": _addr,
+                       "key_name": CONFIG_METADATA_BY_ADDR[_addr],
+                       "readonly": _read_only,
+                       "value": _value}
+        return return_data
+        # 跳过异步,直接查询某个数据信息
+    def get_basic_info_mcu_without_async(self, data,fiddler_cmd=0):
+        """
+        fiddler_cmd :只接收指定的命令内容
+        """
+        try:
+            # 清空接收数据
+            self.serial_ins.clearn_flush()
+            self.serial_ins.write_cmd(data, is_print=True)
+            time.sleep(0.06)
+            r_data = self.get_basic_info_mcu(max_retries=1,fiddler_cmd=fiddler_cmd)
+            # print("264----------r_data:", r_data)
+        except BaseException as e:
+            print("302---e",e)
+            r_data = []
+
+        self.async_lock.release()
+        return r_data
+    def dynamic_parameter_issuance(self, receive_data):
+        print("dynamic_parameter_issuance   receive_data", receive_data)
+        func_code, status_code, out_par_data_list = dynamic_parameter_issuance_get(
+            receive_data
+        )
+        r_data = {
+            "func_code": func_code,
+            "status_code": status_code,
+            "out_par_data_list": out_par_data_list,
+        }
+        print(r_data)
+        return r_data
+
+    # 读取某个寄存器数据
+    def read_register_data_by_usb(self, receive_data):
+        return receive_data
+
+    # 写入某个寄存器数据
+    def write_register_data_by_usb(self, receive_data):
+        return receive_data
+
+    # 获取所有寄存器
+    def get_all_registers_list_by_usb(self, receive_data):
+        byte_list = receive_data[1:]
+        _r_data = []
+        for i in range(0, len(byte_list), 2):
+            if i + 1 < len(byte_list):
+                first_byte = byte_list[i]
+                second_byte = byte_list[i + 1]
+                _addr = first_byte << 8 | second_byte
+                _r_data.append(_addr)
+        return _r_data
 
 
     async def sendCommand(self, command):
     async def sendCommand(self, command):
         await asyncio.sleep(0.01)
         await asyncio.sleep(0.01)

+ 109 - 0
python/utils/utils_func.py

@@ -240,3 +240,112 @@ def get_cutout_image_info(source_image_path):
     data["cutout_image_file_name"] = cutout_image_file_name
     data["cutout_image_file_name"] = cutout_image_file_name
     data["cutout_image_file_extension"] = cutout_image_file_extension
     data["cutout_image_file_extension"] = cutout_image_file_extension
     return data
     return data
+
+
+def dynamic_parameter_issuance_get(receive_data):
+    # 动态解析参数,并进行下发,第一个为功能码,后续为参数。
+    func_code = receive_data[1] << 8 | receive_data[2]
+    status_code = receive_data[3] << 8 | receive_data[4]
+    par_len = receive_data[5]
+    par_data = receive_data[6:]
+    out_par_data_list = []
+    if par_len > 0:
+        chunk_size = len(par_data) // par_len
+        par_data_list = [
+            par_data[i : i + chunk_size] for i in range(0, len(par_data), chunk_size)
+        ]
+        for one_par in par_data_list:
+            start = 0
+            _value = (
+                one_par[start] << 40
+                | one_par[start + 1] << 32
+                | one_par[start + 2] << 24
+                | one_par[start + 3] << 16
+                | one_par[start + 4] << 8
+                | one_par[start + 5]
+            )
+            start = start + 5
+            _dir = 1 if one_par[start + 1] == 1 else -1
+            _type = "int" if one_par[start + 2] == 1 else "float"
+            _precision = one_par[start + 3]
+            if _dir < 0:
+                _value = _value * _dir
+            if _type == "float":
+                if _precision > 0:
+                    _round_x = _precision
+                    _precision = _precision * -1
+                    _value = _value * 10**_precision
+                    _value = round(_value, _round_x)
+
+            out_par_data_list.append(_value)
+    return func_code, status_code, out_par_data_list
+
+
+def calculation_value(value=None):
+    buf = []
+    # 地址、正负、类型(整数、浮点)、精度(0.01)、数据(6个字节)、是否只读
+    _dir = 1 if value >= 0 else 0  # 是否正负
+    _type = 1 if isinstance(value, int) else 0  # 1是整数
+    if _type == 0:
+        _precision = len(str(value).split(".")[1])  # 精度
+        if _precision > 4:
+            _precision = 4
+        abs_int_value = int(abs(value * 10**_precision))
+    else:
+        abs_int_value = abs(value)
+        _precision = 0
+    buf.extend(
+        [
+            0xFF & abs_int_value >> 40,
+            0xFF & abs_int_value >> 32,
+            0xFF & abs_int_value >> 24,
+            0xFF & abs_int_value >> 16,
+            0xFF & abs_int_value >> 8,
+            0xFF & abs_int_value,
+        ]
+    )
+    buf.extend([_dir, _type, _precision])
+    # print(abs_int_value, _dir, _type, _precision)
+    return buf
+
+
+def read_cmd_test(receive_data):
+    if len(receive_data) < 4:
+        return False
+
+    if receive_data[0] == 0x55 and receive_data[1] == 0x55:
+        data_len = receive_data[2]
+        if len(receive_data) < data_len + 4:
+            return False
+        _data = receive_data[3 : data_len + 4]
+        # 校验数据
+        if 0xFF & ~sum(_data[:-1]) == _data[-1]:
+            return _data[:-1]
+        else:
+            return False
+    else:
+        return False
+
+
+# 动态参数生成
+def dynamic_parameter_issuance_send(func_code, status_code, par_data_list=None):
+    # 动态解析参数,并进行下发,第一个为功能码,后续为参数。
+    _buf = [
+        0xFF & func_code >> 8,
+        0xFF & func_code,
+        0xFF & status_code >> 8,
+        0xFF & status_code,
+        0 if not par_data_list else len(par_data_list),
+    ]
+    if par_data_list:
+        for par_data in par_data_list:
+            _buf.extend(calculation_value(par_data))
+    return _buf
+
+
+def cmd_send_test(data):
+    buf = []
+    buf.extend([0x55, 0x55, (0xFF & len(data))])
+    buf.extend(data)
+    buf.extend([0xFF & ~sum(data)])
+    return buf