docstr: Main VisPy Canvas for simulation of physical system.
  
  Parameters
  ----------
  d1 : float
      Length of rod (in meters) from pivot to upper spring.
  d2 : float
      Length of rod (in meters) from pivot to lower spring.
  little_m : float
      Mass of attached cube (in kilograms).
  big_m : float
      Mass of rod (in kilograms).
  spring_k1 : float
      Spring constant of lower spring (in N/m).
  spring_k2 : float
      Spring constant of upper spring (in N/m).
  b : float
      Coefficient of quadratic sliding friction (in kg/m).
  x : float
      Initial x-position of mass (in m).
  x_dot : float
      Initial x-velocity of mass (in m/s).
  theta : float
      Initial angle of rod, with respect to vertical (in radians).
  theta_dot : float
      Initial angular velocity of rod (in rad/s).
  px_len : int
      Length of the rod, in pixels.
  scale : int
      Scaling factor to change size of elements.
  pivot : bool
      Switch for showing/hiding pivot point.
  method : str
      Method to use for updating.
  dt : float
      Time step for simulation.
  font_size : float
      Size of font for text elements, in points.
  
  Notes
  -----
  
  As of right now, the only supported methods are "euler" or
  "runge-kutta". These correspond to an Euler method or an
  order 3 Runge-Kutta method for updating x, theta, x dot, and theta dot.
docstr_tok: ["Main","VisPy","Canvas","for","simulation","of","physical","system",".","Parameters","--","--","--","--","--","d1",":","float","Length","of","rod","(","in","meters",")","from","pivot","to","upper","spring",".","d2",":","float","Length","of","rod","(","in","meters",")","from","pivot","to","lower","spring",".","little_m",":","float","Mass","of","attached","cube","(","in","kilograms",")",".","big_m",":","float","Mass","of","rod","(","in","kilograms",")",".","spring_k1",":","float","Spring","constant","of","lower","spring","(","in","N\/m",")",".","spring_k2",":","float","Spring","constant","of","upper","spring","(","in","N\/m",")",".","b",":","float","Coefficient","of","quadratic","sliding","friction","(","in","kg\/m",")",".","x",":","float","Initial","x-position","of","mass","(","in","m",")",".","x_dot",":","float","Initial","x-velocity","of","mass","(","in","m\/s",")",".","theta",":","float","Initial","angle","of","rod",",","with","respect","to","vertical","(","in","radians",")",".","theta_dot",":","float","Initial","angular","velocity","of","rod","(","in","rad\/s",")",".","px_len",":","int","Length","of","the","rod",",","in","pixels",".","scale",":","int","Scaling","factor","to","change","size","of","elements",".","pivot",":","bool","Switch","for","showing\/hiding","pivot","point",".","method",":","str","Method","to","use","for","updating",".","dt",":","float","Time","step","for","simulation",".","font_size",":","float","Size","of","font","for","text","elements",",","in","points",".","Notes","--","--","-","As","of","right","now",",","the","only","supported","methods","are","``","euler","''","or","''","runge-kutta","''",".","These","correspond","to","an","Euler","method","or","an","order","3","Runge-Kutta","method","for","updating","x",",","theta",",","x","dot",",","and","theta","dot","."]
code: def __init__(
      self,
      d1=None,
      d2=None,
      little_m=None,
      big_m=None,
      spring_k1=None,
      spring_k2=None,
      b=None,
      x=None,
      x_dot=None,
      theta=None,
      theta_dot=None,
      px_len=None,
      scale=None,
      pivot=False,
      method="Euler",
      dt=None,
      font_size=None,
  ):
      """
      Main VisPy Canvas for simulation of physical system.
  
      Parameters
      ----------
      d1 : float
          Length of rod (in meters) from pivot to upper spring.
      d2 : float
          Length of rod (in meters) from pivot to lower spring.
      little_m : float
          Mass of attached cube (in kilograms).
      big_m : float
          Mass of rod (in kilograms).
      spring_k1 : float
          Spring constant of lower spring (in N/m).
      spring_k2 : float
          Spring constant of upper spring (in N/m).
      b : float
          Coefficient of quadratic sliding friction (in kg/m).
      x : float
          Initial x-position of mass (in m).
      x_dot : float
          Initial x-velocity of mass (in m/s).
      theta : float
          Initial angle of rod, with respect to vertical (in radians).
      theta_dot : float
          Initial angular velocity of rod (in rad/s).
      px_len : int
          Length of the rod, in pixels.
      scale : int
          Scaling factor to change size of elements.
      pivot : bool
          Switch for showing/hiding pivot point.
      method : str
          Method to use for updating.
      dt : float
          Time step for simulation.
      font_size : float
          Size of font for text elements, in points.
  
      Notes
      -----
  
      As of right now, the only supported methods are "euler" or
      "runge-kutta". These correspond to an Euler method or an
      order 3 Runge-Kutta method for updating x, theta, x dot, and theta dot.
  
      """
  
      app.Canvas.__init__(
          self, title="Wiggly Bar", size=(800, 800), create_native=False
      )
  
      # Some initialization constants that won't change
      self.standard_length = 0.97 + 0.55
      self.center = np.asarray((500, 450))
      self.visuals = []
  
      self._set_up_system(
          d1=d1,
          d2=d2,
          little_m=little_m,
          big_m=big_m,
          spring_k1=spring_k1,
          spring_k2=spring_k2,
          b=b,
          x=x,
          x_dot=x_dot,
          theta=theta,
          theta_dot=theta_dot,
          px_len=px_len,
          scale=scale,
          pivot=pivot,
          method=method,
          dt=dt,
          font_size=font_size,
      )
  
      piv_x_y_px = np.asarray(
          (
              self.pivot_loc_px * np.sin(self.theta),
              -1 * self.pivot_loc_px * (np.cos(self.theta)),
          )
      )
  
      # Make the spring points
      points = make_spring(
          height=self.px_len / 4, radius=self.px_len / 24
      )
  
      # Put up a text visual to display time info
      self.font_size = 24.0 if font_size is None else font_size
      self.text = visuals.TextVisual(
          "0:00.00",
          color="white",
          pos=[50, 250, 0],
          anchor_x="left",
          anchor_y="bottom",
      )
      self.text.font_size = self.font_size
  
      # Let's put in more text so we know what method is being used to
      # update this
      self.method_text = visuals.TextVisual(
          "Method: {}".format(self.method),
          color="white",
          pos=[50, 250, 0],
          anchor_x="left",
          anchor_y="top",
      )
      self.method_text.font_size = 2 / 3 * self.font_size
  
      # Get the pivoting bar ready
      self.rod = visuals.BoxVisual(
          width=self.px_len / 40,
          height=self.px_len / 40,
          depth=self.px_len,
          color="white",
      )
      self.rod.transform = transforms.MatrixTransform()
      self.rod.transform.scale(
          (self.scale, self.scale * self.rod_scale, 0.0001)
      )
      self.rod.transform.rotate(np.rad2deg(self.theta), (0, 0, 1))
      self.rod.transform.translate(self.center - piv_x_y_px)
  
      # Show the pivot point (optional)
      pivot_center = (self.center[0], self.center[1], -self.px_len / 75)
      self.center_point = visuals.SphereVisual(
          radius=self.px_len / 75, color="red"
      )
      self.center_point.transform = transforms.MatrixTransform()
      self.center_point.transform.scale(
          (self.scale, self.scale, 0.0001)
      )
      self.center_point.transform.translate(pivot_center)
  
      # Get the upper spring ready.
      self.spring_2 = visuals.TubeVisual(
          points, radius=self.px_len / 100, color=(0.5, 0.5, 1, 1)
      )
      self.spring_2.transform = transforms.MatrixTransform()
      self.spring_2.transform.rotate(90, (0, 1, 0))
      self.spring_2.transform.scale((self.scale, self.scale, 0.0001))
      self.spring_2.transform.translate(self.center + self.s2_loc)
  
      # Get the lower spring ready.
      self.spring_1 = visuals.TubeVisual(
          points, radius=self.px_len / 100, color=(0.5, 0.5, 1, 1)
      )
      self.spring_1.transform = transforms.MatrixTransform()
      self.spring_1.transform.rotate(90, (0, 1, 0))
      self.spring_1.transform.scale(
          (
              self.scale
              * (
                  1.0
                  - (self.x * self.px_per_m)
                  / (self.scale * self.px_len / 2)
              ),
              self.scale,
              0.0001,
          )
      )
      self.spring_1.transform.translate(self.center + self.s1_loc)
  
      # Finally, prepare the mass that is being moved
      self.mass = visuals.BoxVisual(
          width=self.px_len / 4,
          height=self.px_len / 8,
          depth=self.px_len / 4,
          color="white",
      )
      self.mass.transform = transforms.MatrixTransform()
      self.mass.transform.scale((self.scale, self.scale, 0.0001))
      self.mass.transform.translate(self.center + self.mass_loc)
  
      # Append all the visuals
      self.visuals.append(self.center_point)
      self.visuals.append(self.rod)
      self.visuals.append(self.spring_2)
      self.visuals.append(self.spring_1)
      self.visuals.append(self.mass)
      self.visuals.append(self.text)
      self.visuals.append(self.method_text)
  
      # Set up a timer to update the image and give a real-time rendering
      self._timer = app.Timer("auto", connect=self.on_timer, start=True)
  
imports: from __future__ import division, print_function, absolute_import
  from vispy import app, visuals
  from vispy.visuals import transforms
  from vispy.io import load_data_file
  import sys
  import numpy
  import string
  import logging
  import traceback
  from PyQt5 import QtCore, QtGui, QtWidgets
label_desc: Use image node_id 1 to create a new WigglyBar object from inherited base classes: app with example: obj = WigglyBar(d1, d2, little_m, big_m, spring_k1, spring_k2, b, x, x_dot, theta, theta_dot, px_len, scale, pivot, method, dt, font_size)