无法使用 python 包对绘图进行动画处理



我正在尝试从我在名为 "pytrajectory" 的控制系统上找到的软件包中获取一些示例代码。这取决于 sympynumpy ,两者都是我在 Ubuntu 16.04 上通过 anaconda 添加的。以下是我一直尝试运行的示例代码:

'''
This example of the inverted pendulum demonstrates the basic usage of
PyTrajectory as well as its visualisation capabilities.
'''
# import all we need for solving the problem
from pytrajectory import ControlSystem
import numpy as np
from sympy import cos, sin
from numpy import pi
# the next imports are necessary for the visualisatoin of the system
import sys
import matplotlib as mpl
from pytrajectory.visualisation import Animation
# first, we define the function that returns the vectorfield
def f(x,u):
    x1, x2, x3, x4 = x  # system variables
    u1, = u             # input variable
    l = 0.5     # length of the pendulum
    g = 9.81    # gravitational acceleration
    # this is the vectorfield
    ff = [          x2,
                    u1,
                    x4,
            (1/l)*(g*sin(x3)+u1*cos(x3))]
    return ff
# then we specify all boundary conditions
a = 0.0
xa = [0.0, 0.0, pi, 0.0]
b = 2.0
xb = [0.0, 0.0, 0.0, 0.0]
ua = [0.0]
ub = [0.0]
# now we create our Trajectory object and alter some method parameters via the keyword arguments
S = ControlSystem(f, a, b, xa, xb, ua, ub, kx=5, use_chains=False)
# time to run the iteration
S.solve()

# now that we (hopefully) have found a solution,
# we can visualise our systems dynamic
# therefore we define a function that draws an image of the system
# according to the given simulation data
def draw(xt, image):
    # to draw the image we just need the translation `x` of the
    # cart and the deflection angle `phi` of the pendulum.
    x = xt[0]
    phi = xt[2]
    # next we set some parameters
    car_width = 0.05
    car_heigth = 0.02
    rod_length = 0.5
    pendulum_size = 0.015
    # then we determine the current state of the system
    # according to the given simulation data
    x_car = x
    y_car = 0
    x_pendulum = -rod_length * sin(phi) + x_car
    y_pendulum = rod_length * cos(phi)
    # now we can build the image
    # the pendulum will be represented by a black circle with
    # center: (x_pendulum, y_pendulum) and radius `pendulum_size
    pendulum = mpl.patches.Circle(xy=(x_pendulum, y_pendulum), radius=pendulum_size, color='black')
    # the cart will be represented by a grey rectangle with
    # lower left: (x_car - 0.5 * car_width, y_car - car_heigth)
    # width: car_width
    # height: car_height
    car = mpl.patches.Rectangle((x_car-0.5*car_width, y_car-car_heigth), car_width, car_heigth,
                                fill=True, facecolor='grey', linewidth=2.0)
    # the joint will also be a black circle with
    # center: (x_car, 0)
    # radius: 0.005
    joint = mpl.patches.Circle((x_car,0), 0.005, color='black')
    # and the pendulum rod will just by a line connecting the cart and the pendulum
    rod = mpl.lines.Line2D([x_car,x_pendulum], [y_car,y_pendulum],
                            color='black', zorder=1, linewidth=2.0)
    # finally we add the patches and line to the image
    image.patches.append(pendulum)
    image.patches.append(car)
    image.patches.append(joint)
    image.lines.append(rod)
    # and return the image
    return image
if 'no-pickle' in sys.argv:
    # here we save the simulation results so we don't have to run
    # the iteration again in case the following fails
    S.save(fname='ex0_InvertedPendulumSwingUp.pcl')
# now we can create an instance of the `Animation` class 
# with our draw function and the simulation results
#
# to plot the curves of some trajectories along with the picture
# we also pass the appropriate lists as arguments (see documentation)
if 'plot' in sys.argv or 'animate' in sys.argv:
    A = Animation(drawfnc=draw, simdata=S.sim_data, 
                  plotsys=[(0,'x'), (2,'phi')], plotinputs=[(0,'u')])
    # as for now we have to explicitly set the limits of the figure
    # (may involves some trial and error)
    xmin = np.min(S.sim_data[1][:,0]); xmax = np.max(S.sim_data[1][:,0])
    A.set_limits(xlim=(xmin - 0.5, xmax + 0.5), ylim=(-0.6,0.6))
if 'plot' in sys.argv:
    A.show(t=S.b)
if 'animate' in sys.argv:
    # if everything is set, we can start the animation
    # (might take some while)
    A.animate()
    # then we can save the animation as a `mp4` video file or as an animated `gif` file
    A.save('ex0_InvertedPendulum.gif')

它应该直接工作并动画倒立钟摆的情节,但我得到以下错误:

Traceback (most recent call last):
  File "animate.py", line 135, in <module>
    A.save('ex0_InvertedPendulum.gif')
  File "/home/rwl0006/.local/lib/python2.7/site-packages/pytrajectory/visualisation.py", line 399, in save
    self.anim.save(fname, writer='imagemagick', fps=fps)
  File "/home/rwl0006/anaconda2/lib/python2.7/site-packages/matplotlib/animation.py", line 1254, in save
    anim._init_draw()
  File "/home/rwl0006/anaconda2/lib/python2.7/site-packages/matplotlib/animation.py", line 1792, in _init_draw
    self._draw_frame(next(self.new_frame_seq()))
  File "/home/rwl0006/anaconda2/lib/python2.7/site-packages/matplotlib/animation.py", line 1814, in _draw_frame
    self._drawn_artists = self._func(framedata, *self._args)
  File "/home/rwl0006/.local/lib/python2.7/site-packages/pytrajectory/visualisation.py", line 341, in _animate
    print "frame = {f}, t = {t}, x = {x}, u = {u}".format(f=frame, t=t[i], x=xt[i,:], u=ut[i,:])
IndexError: only integers, slices (`:`), ellipsis (`...`), numpy.newaxis (`None`) and integer or boolean arrays are valid indices

对不起,新手问题,但我真的碰壁了。如果需要,以下是文档的链接:https://pytrajectory.readthedocs.io/en/master/

它最终成为变量类型的问题,我认为我是一个迭代计数器值,当它应该只是一个整数 0 时,它被传递了一个 0.0。我通过修改visualisation.py文件来修复此错误,从而将值 i 重新转换为整数。

i = ______
i = int(i)

最新更新