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

Webots机械臂夹爪循环测试异常:CSV导出与力值循环问题排查

Webots机械臂力测试循环与CSV导出问题修复

核心问题

  1. 外层循环无法推进:Webots的robot.step()是仿真主循环,一旦进入这个while循环,代码会一直停留在当前力值的测试流程中,外层for循环完全没机会执行下一个力值的迭代,所以只会使用第一个力值,也只会生成第一个CSV文件。
  2. 状态变量未重置:即便能跳出while循环,timer、arm_pos等变量仍保留上次测试后的状态,第二次循环会直接跳过初始动作步骤,无法完成完整测试。
  3. timer重置语法错误:代码里的timer == 0是相等判断,不是赋值操作,应该写成timer = 0;且原逻辑没有跳出while循环的语句,导致测试流程无法终止。
  4. 缺失实际数据写入:原代码仅写入CSV表头,没有把每次仿真step采集到的实际数据写入文件,文件内容只有表头。

修复方案

1. 让单次测试完成后跳出仿真循环

在timer达到380后,添加break语句跳出while循环,让外层for循环能继续执行下一个力值的测试。

2. 每次测试前重置状态变量

在for循环内部、打开CSV文件之前,将timer、arm_pos、wst_pos、fgr_pos重置为初始值,保证每次测试都从初始状态开始。

3. 修正timer重置的语法错误

把timer == 0改为timer = 0,配合break语句终止当前测试流程。

4. 补充数据写入逻辑

在主循环的每次step中,采集传感器数据并写入对应的CSV文件。

修复后的代码示例

import csv

# 根据实际场景定义全局变量
MASS = 1.0
BOX_WIDTH = 0.2
timestep = int(robot.getBasicTimeStep())
# 初始化电机设备(需与你的Webots场景配置匹配)
finger_motor = robot.getDevice('finger_motor')
arm_motor = robot.getDevice('arm_motor')
wrist_motor = robot.getDevice('wrist_motor')

forcelist = range(1000, 5000, 250)

for i in forcelist:
    # 每次测试前重置所有状态变量
    timer = 0
    arm_pos = 0.0  # 替换为你的机械臂初始位置
    wst_pos = 0.0
    fgr_pos = 0.0  # 替换为你的夹爪初始位置
    
    # 创建当前力值对应的CSV文件
    with open(f"TwoFingerGripper_force={i}_mass={MASS}_width={BOX_WIDTH}.csv", 'w', encoding='UTF8') as f:
        writer = csv.writer(f)
        # 写入表头
        writer.writerow([
            "dsc_value","com_x","com_y","com_z",
            "speed_lin_x","speed_lin_y","speed_lin_z",
            "speed_rot_0", "speed_rot_1", "speed_rot_2", 
            "gripper_force", "power_input", "battery"
        ])
        
        # 当前力值的测试循环
        while robot.step(timestep) != -1:
            if timer < 60:
                finger_motor.setTorque(0.5)
            elif timer < 120:
                finger_motor.setForce(i)
                if arm_pos <= 1.6:
                    arm_pos += 0.04
            elif timer < 180:
                finger_motor.setForce(i)
                if wst_pos <= 3.14159265:
                    wst_pos += 0.1
            elif timer < 240:
                finger_motor.setForce(i)
                if wst_pos > 0:
                    wst_pos -= 0.1
            elif timer < 300:
                finger_motor.setForce(i)
                if arm_pos > 0:
                    arm_pos -= 0.04
            elif timer < 360:
                if fgr_pos < 0:
                    fgr_pos += 0.02
            elif timer >= 380:
                # 重置timer并跳出循环,结束当前测试
                timer = 0
                break  # 跳出while循环,进入下一个力值测试
            
            timer += 1  

            # 替换为实际的传感器数据读取逻辑
            dsc_value = 0  # 示例值,需替换为真实采集数据
            com_x, com_y, com_z = 0, 0, 0
            speed_lin_x, speed_lin_y, speed_lin_z = 0, 0, 0
            speed_rot_0, speed_rot_1, speed_rot_2 = 0, 0, 0
            gripper_force = i
            power_input = 0  # 示例值,需替换为真实采集数据
            battery = 0  # 示例值,需替换为真实采集数据
            
            # 将数据写入CSV
            writer.writerow([
                dsc_value, com_x, com_y, com_z,
                speed_lin_x, speed_lin_y, speed_lin_z,
                speed_rot_0, speed_rot_1, speed_rot_2,
                gripper_force, power_input, battery
            ])

            ledCtrl()    
            arm_motor.setPosition(arm_pos)
            wrist_motor.setPosition(wst_pos)
            finger_motor.setPosition(-fgr_pos)

额外提醒

  • 确保ledCtrl()函数内无阻塞逻辑,避免影响仿真循环推进。
  • 传感器数据需根据Webots场景中使用的设备读取,比如用GPS模块的getValues()获取位置、惯性单元的getAngularVelocity()获取旋转速度。
  • 若需重置整个仿真场景,可在每次测试结束后调用robot.simulationReset(),但该函数会重置所有设备状态,需配合状态变量重置使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 15:25:04