用Python玩转INCA标定:Excel一键修改+自动记录日志(小白友好版)

**为什么需要这个工具?**
在汽车电子标定工作中,手动修改INCA参数、反复记录数据,不仅费时还容易出错。  
今天分享一个**“懒人神器”**:用Python从Excel读取参数,自动写入INCA,并生成操作日志。全程无需手动操作,杜绝手抖填错数据!  
(代码已优化,对新手友好,复制即用!)

一、准备工作
1. 环境配置
  • INCA安装:确保电脑已安装ETAS INCA 7.1+(其他版本需调整COM接口路径)。

  • Python库安装:以下库缺一不可:

    pip install pandas pythonnet clr
2. 文件结构
  • main.py:主程序

import time

from excel_handler import ExcelHandler
from inca_controller import IncaController
from logger import DataLogger


def main():
    # 初始化模块
    logger = DataLogger()
    excel = ExcelHandler(r'inca.xlsx')
    controller = IncaController()
    #  Excel inca 变量名赋值给python
    name_value = "UDC_swtSetP_C"
    time_value = "tiem"
    # 从Excel读取标定参数并写入INCA
    cal_data = excel.read_calibration_data()
    print(cal_data)
    for item in cal_data:
        try:
            time.sleep(item[time_value])
            controller.write_calibration(name_value, item[name_value], item[time_value])
            # controller.write_calibration(item['name1'], item['name1_value'],item['time_value'])
            # logger.log_operation('EXCEL_IMPORT', item['name'],  item['name_value'], 'IMPORTED')

        except:
            print("暂停")
            break
    # 保存测量数据到Excel
    # measure_data = [{'name': 'Oil_pSwmp', 'value': controller.read_measurement('Oil_pSwmp')}]
    # excel.save_measurement_data(measure_data)


if __name__ == "__main__":
    main()
  • excel_handler.py:处理Excel读写

import os

import pandas as pd


class ExcelHandler:
    def __init__(self, file_path):
        # 存储文件路径以便于后续使用
        self.file_path = file_path
        self.ext = os.path.splitext(file_path)[1].lower()

    def read_calibration_data(self):
        """读取Excel中的标定参数"""
        print(self.ext)
        try:
            if self.ext in ['.xls', '.xlsx']:
                df = pd.read_excel(self.file_path, sheet_name='Sheet1', header=0)

            elif self.ext == '.csv':
                # 读取CSV文件,自动推断分隔符
                df = pd.read_csv(self.file_path, header=0, sep=None, engine='python')
            elif self.ext == '.txt':
                # 读取文本文件,自动检测分隔符(支持空格/tab/逗号等)
                df = pd.read_table(self.file_path, header=0, sep='\s+', engine='python')
            else:
                raise ValueError("不支持的文件格式,仅支持xls/xlsx/csv/txt")

            return df.to_dict('records')  # 返回字典列表[1]()
        except Exception as e:
            print(f"Excel读取失败: {str(e)}")
            return []

    def save_measurement_data(self, data):
        """保存测量数据到Excel"""
        try:
            df = pd.DataFrame(data)
            df.to_excel(self.file_path, sheet_name='Sheet3', index=False)
        except Exception as e:
            print(f"Excel保存失败: {str(e)}")
  • inca_controller.py:控制INCA的核心

import sys
import time

import clr

import logger

# 添加INCA-COM组件引用
sys.path.append(r'C:\ETAS\INCA7.1\cebra')  # 按实际路径修改
clr.AddReference('incacom')
clr.AddReference('Etas.Base.ComSupport')

# 导入API命名空间
from de.etas.cebra.toolAPI import Inca


class IncaController:
    def __init__(self):
        """初始化INCA连接"""
        self.logger = logger.DataLogger()
        try:
            self.inca = Inca.Inca()  # 创建INCA实例
            # print("INCA版本:", self.inca.APIVersion())   # 获取当前软件版本
            self.experiment = self.inca.GetOpenedExperiment()  # 获取当前实验
            # print(self.experiment)
        except Exception as e:
            print(f"INCA连接失败: {str(e)}")
            sys.exit(1)

    def read_measurement(self, var_name):
        # 读取测量变量值
        measure = None
        try:
            measure = self.experiment.GetMeasureElement(var_name)
            measure1 = measure.GetValue()
            return measure1.GetDoublePhysValue()
        except Exception as e:
            print(f"读取测量变量{var_name}失败: {str(e)}")
            return None
        finally:
            if measure is not None:
                del measure

    def write_calibration(self, cal_name, new_value, time_value):
        """
        写入标定参数
        该方法用于更新实验中的一个标定参数,并记录该操作的日志如果更新失败,会捕获异常并记录错误日志
        参数:
        cal_name (str): 标定参数的名称
        new_value (float): 标定参数的新值
        time_value (float): 标定参数稳定所需的时间
        """
        # 确保标定参数写入前,程序已经启动一段时间,以确保系统稳定
        time.sleep(0.2)
        try:
            # 获取指定名称的标定元素
            cal = self.experiment.GetCalibrationElement(cal_name)
            # 获取当前标定参数的值
            cal1 = cal.GetValue()
            # print(cal1)
            # 设置新的标定参数值,并获取设置后的状态
            cal2 = cal1.SetDoublePhysValue(new_value)
            # 记录操作时间
            inca_time = time.strftime("%Y-%m-%d  %H:%M:%S")
            print(f"{inca_time}-标定参数{cal_name}已更新为{new_value}稳定时间为:{time_value}s,{cal2}")
            # 记录成功的标定操作日志
            self.logger.log_operation('CALIBRATION', cal_name, new_value, time_value, 'SUCCESS')
        except Exception as e:
            # 打印标定参数更新失败的错误信息
            print(f"写入标定参数{cal_name}失败: {str(e)}")
            # 记录失败的标定操作日志
            self.logger.log_operation('CALIBRATION', cal_name, new_value, time_value, 'FAILED')

    # def write_calibrations_batch(self, cal_list):
    #     """批量写入标定参数   功能还未完善"""
    #     for cal_name, new_value, time_value in cal_list:
    #         self.write_calibration(cal_name, new_value, time_value)

    def __del__(self):
        """释放INCA资源"""
        if hasattr(self, 'inca'):
            del self.inca


if __name__ == "__main__":
    # 调用 IncaController类
    controller = IncaController()

    # 测量值变量名  和 调用读取测量值函数
    # Measurename = 'Oil_pSwmp'
    # MeasureValue = controller.read_measurement(Measurename)
    # print(MeasureValue)

    setcalname = "UDC_swtSetP_C"
    setcalValue = 3
    controller.write_calibration(setcalname, setcalValue, 3)

    # 批量标定调用   功能还未完善
    # cal_list = [
    #     ("UDC_swtSetP_C", 3, 1),
    #     ("AnotherCalParam", 5, 2)
    # ]
    # controller.write_calibrations_batch(cal_list)
  • logger.py:记录操作日志

import time
import csv


class DataLogger:
    def __init__(self, log_file='operation_log.csv'):

        self.log_file = log_file

        self._init_log_file()

    def _init_log_file(self):
        """初始化日志文件表头[2]()"""
        with open(self.log_file, 'a', newline='') as f:
            writer = csv.writer(f)
            writer.writerow([' 时间', '操作类型', '变量名',  '新值', "稳定时间",'状态'])

    def log_operation(self, op_type, var_name, new_val, time_value,status):
        """记录操作日志[5]()"""
        timestamp = time.strftime("%Y-%m-%d  %H:%M:%S")
        with open(self.log_file, 'a', newline='') as f:
            writer = csv.writer(f)
            writer.writerow([timestamp, op_type, var_name,  new_val, time_value,status])
  • inca.xlsx:标定参数表((inca_com/inca.xlsx · 肖丰/Py_Inca_excel - Gitee.com) )

用Python玩转INCA标定:Excel一键修改+自动记录日志(小白友好版)_第1张图片

3. Excel参数表格式
  • 文件名为inca.xlsx,Sheet名称为Sheet1

  • 表格需包含两列:UDC_swtSetP_C(参数值)和tiem(稳定时间),示例:

UDC_swtSetP_C tiem
3.0 1.5
4.2 2.0

二、代码核心逻辑(小白秒懂版)
1. Excel读取模块
  • 功能:像“翻译官”一样,把Excel表格里的参数变成Python能理解的字典。

  • 代码亮点

    • 支持.xlsx.csv.txt三种格式。

    • 自动识别分隔符,避免格式不对齐的坑。

2. INCA控制模块
  • 功能:扮演“遥控器”角色,通过COM接口操控INCA。

  • 关键步骤

    1. 连接INCA → 2. 获取当前实验 → 3. 写入参数。

  • 避坑提示

    • 路径中的C:\ETAS\INCA7.1\cebra需根据实际安装路径修改!

    • 写入前强制休眠0.2秒(防止手速太快,系统卡顿)。

3. 日志模块
  • 功能:像“黑匣子”一样记录每次操作,方便甩锅(划掉)追溯问题。

  • 日志格式

    时间, 操作类型, 变量名, 新值, 稳定时间, 状态
    2023-10-01 14:30:00, CALIBRATION, UDC_swtSetP_C, 3.0, 1.5, SUCCESS


三、使用步骤
  1. 配置Excel:按上述格式填写参数。

  2. 修改路径:在inca_controller.py中调整INCA安装路径。

  3. 运行程序:双击main.py或命令行执行:

    python main.py

  4. 查看结果

    • INCA中参数自动更新。

    • 同级目录下生成operation_log.csv,记录详细操作。


四、常见问题
1. INCA连接失败
  • 症状:报错INCA连接失败

  • 排查

    • 检查路径中的反斜杠\是否改为\\/

    • 关闭INCA重试(有时需重启软件)。

2. Excel读取为空
  • 症状:程序输出空列表。

  • 排查

    • 确认Sheet名称是否为Sheet1

    • 检查Excel列名是否包含空格(比如tiem不能写成time)。

3. 日志未生成
  • 症状:找不到operation_log.csv

  • 解决:以管理员身份运行程序(避免权限不足)。


五、进阶玩法
  • 批量修改:在Excel中增加多列参数,解锁“一条龙”修改(需扩展代码)。

  • 自动截图:在写入参数后调用截图工具,保存INCA界面状态。

  • 邮件报警:当状态为FAILED时,自动发送邮件通知(加3行代码即可)。


六、总结

这个工具的核心逻辑就是:Excel喂数据 → Python干活 → INCA执行 → 日志留痕。 对新手来说,只需关注Excel配置和路径修改,其他交给代码。即使你是编程小白,也能轻松驾驭INCA标定!


立即体验代码:[Github链接](Py_Inca_excel: 专注于Python环境下Excel文件处理和inca标定值修改的开源库,提供高效的数据读写和修改inca标定值等多种业务场景。 - Gitee.com) 问题交流:评论区留言,有问必答!

你可能感兴趣的:(python,excel,开发语言)