Python中如何实现范围正反向循环?角度往复运动控制求助
问题描述
我想要实现如图所示的运动控制。角度变化遵循公式:theta = Amp*np.sin(2*np.pi*ftheta*p)。我正在对时间变量p进行循环,该公式中仅p为变量,其余参数均保持不变。请问如何让角度达到振幅值后停止正向变化,转而开始反向变化直至达到负振幅值?
用户提供的原始代码:
import numpy as np import matplotlib.pyplot as plt import math r=20 h=1.7 num_of_steps=100 emp=3 phi = [] theta = [] time=np.arange(0,100,1) fphi = 1 ftheta = 1 Amp = 90 for j in time: kampas = np.degrees(2*np.pi*fphi*j) kitaskampas = np.degrees(np.sin(2*np.pi*ftheta*j)) if kampas > 360: temp = math.floor(kampas/360) sukasi = round(kampas - 360*temp) print(sukasi) phi.append(sukasi) if kitaskampas == Amp: print(phi)
解决方案
首先指出你代码中的核心问题:
- 公式实现错误:
kitaskampas应该是Amp * np.sin(2*np.pi*ftheta*j),而非对sin结果转角度——np.sin输出范围是[-1,1],乘以Amp才是目标角度范围[-Amp, Amp]。 - 极值判断无效:浮点运算中
kitaskampas == Amp几乎永远不会触发,需改用趋势检测或直接生成符合需求的波形。
针对你的需求,提供两种可行方案:
方案一:生成三角波(线性往返运动)
如果需要到达极值后匀速反向的运动效果,直接用三角波代替正弦波更贴合需求:
import numpy as np import matplotlib.pyplot as plt Amp = 90 ftheta = 1 # 频率,控制往返速度 time = np.arange(0, 100, 1) theta = [] for p in time: # 计算周期内的位置,周期T=1/ftheta cycle_pos = (p * ftheta) % 1 if cycle_pos < 0.5: # 正向阶段:从 -Amp 到 Amp current_theta = -Amp + 4 * Amp * cycle_pos else: # 反向阶段:从 Amp 到 -Amp current_theta = Amp - 4 * Amp * (cycle_pos - 0.5) theta.append(current_theta) # 可视化验证 plt.plot(time, theta) plt.ylabel('Theta (degrees)') plt.xlabel('Time p') plt.show()
方案二:正弦波趋势检测(平滑过渡运动)
如果希望保留正弦曲线的平滑运动,同时检测极值并切换方向,可通过比较当前与上一步的角度值判断趋势:
import numpy as np import matplotlib.pyplot as plt Amp = 90 ftheta = 1 time = np.arange(0, 100, 0.1) # 更小步长提升检测精度 theta = [] prev_theta = None direction = 1 # 1=正向,-1=反向 for p in time: current_theta = Amp * np.sin(2 * np.pi * ftheta * p) theta.append(current_theta) # 检测极值并切换方向 if prev_theta is not None: if direction == 1 and current_theta < prev_theta: print(f"到达正振幅 {Amp:.2f},开始反向") direction = -1 elif direction == -1 and current_theta > prev_theta: print(f"到达负振幅 {-Amp:.2f},开始正向") direction = 1 prev_theta = current_theta # 可视化验证 plt.plot(time, theta) plt.axhline(y=Amp, color='r', linestyle='--', label='Amp') plt.axhline(y=-Amp, color='r', linestyle='--', label='-Amp') plt.legend() plt.ylabel('Theta (degrees)') plt.xlabel('Time p') plt.show()
内容的提问来源于stack exchange,提问作者SvylantisCPU
相关产品推荐
相关产品推荐

