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

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)

解决方案

首先指出你代码中的核心问题:

  1. 公式实现错误:kitaskampas应该是Amp * np.sin(2*np.pi*ftheta*j),而非对sin结果转角度——np.sin输出范围是[-1,1],乘以Amp才是目标角度范围[-Amp, Amp]。
  2. 极值判断无效:浮点运算中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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 21:30:53