Webots机械臂夹爪循环测试异常:CSV导出与力值循环问题排查
Webots机械臂力测试循环与CSV导出问题修复
核心问题
- 外层循环无法推进:Webots的
robot.step()是仿真主循环,一旦进入这个while循环,代码会一直停留在当前力值的测试流程中,外层for循环完全没机会执行下一个力值的迭代,所以只会使用第一个力值,也只会生成第一个CSV文件。 - 状态变量未重置:即便能跳出while循环,
timer、arm_pos等变量仍保留上次测试后的状态,第二次循环会直接跳过初始动作步骤,无法完成完整测试。 - timer重置语法错误:代码里的
timer == 0是相等判断,不是赋值操作,应该写成timer = 0;且原逻辑没有跳出while循环的语句,导致测试流程无法终止。 - 缺失实际数据写入:原代码仅写入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
相关产品推荐
相关产品推荐

