157 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			157 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/*
 | 
						|
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
						|
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
						|
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
						|
 */
 | 
						|
#pragma once
 | 
						|
 | 
						|
#include <functional>
 | 
						|
 | 
						|
namespace okapi {
 | 
						|
class FlywheelSimulator {
 | 
						|
  public:
 | 
						|
  /**
 | 
						|
   * A simulator for an inverted pendulum. The center of mass of the system changes as the link
 | 
						|
   * rotates (by default, you can set a new torque function with setExternalTorqueFunction()).
 | 
						|
   */
 | 
						|
  explicit FlywheelSimulator(double imass = 0.01,
 | 
						|
                             double ilinkLen = 1,
 | 
						|
                             double imuStatic = 0.1,
 | 
						|
                             double imuDynamic = 0.9,
 | 
						|
                             double itimestep = 0.01);
 | 
						|
 | 
						|
  virtual ~FlywheelSimulator();
 | 
						|
 | 
						|
  /**
 | 
						|
   * Step the simulation by the timestep.
 | 
						|
   *
 | 
						|
   * @return the current angle
 | 
						|
   */
 | 
						|
  double step();
 | 
						|
 | 
						|
  /**
 | 
						|
   * Step the simulation by the timestep.
 | 
						|
   *
 | 
						|
   * @param itorque new input torque
 | 
						|
   * @return the current angle
 | 
						|
   */
 | 
						|
  double step(double itorque);
 | 
						|
 | 
						|
  /**
 | 
						|
   * Sets the torque function used to calculate the torque due to external forces. This torque gets
 | 
						|
   * summed with the input torque.
 | 
						|
   *
 | 
						|
   * For example, the default torque function has the torque due to gravity vary as the link swings:
 | 
						|
   * [](double angle, double mass, double linkLength) {
 | 
						|
   *   return (linkLength * std::cos(angle)) * (mass * -1 * gravity);
 | 
						|
   * }
 | 
						|
   *
 | 
						|
   * @param itorqueFunc the torque function. The return value is the torque due to external forces
 | 
						|
   */
 | 
						|
  void setExternalTorqueFunction(
 | 
						|
    std::function<double(double angle, double mass, double linkLength)> itorqueFunc);
 | 
						|
 | 
						|
  /**
 | 
						|
   * Sets the input torque. The input will be bounded by the max torque.
 | 
						|
   *
 | 
						|
   * @param itorque new input torque
 | 
						|
   */
 | 
						|
  void setTorque(double itorque);
 | 
						|
 | 
						|
  /**
 | 
						|
   * Sets the max torque. The input torque cannot exceed this maximum torque.
 | 
						|
   *
 | 
						|
   * @param imaxTorque new maximum torque
 | 
						|
   */
 | 
						|
  void setMaxTorque(double imaxTorque);
 | 
						|
 | 
						|
  /**
 | 
						|
   * Sets the current angle.
 | 
						|
   *
 | 
						|
   * @param iangle new angle
 | 
						|
   **/
 | 
						|
  void setAngle(double iangle);
 | 
						|
 | 
						|
  /**
 | 
						|
   * Sets the mass (kg).
 | 
						|
   *
 | 
						|
   * @param imass new mass
 | 
						|
   */
 | 
						|
  void setMass(double imass);
 | 
						|
 | 
						|
  /**
 | 
						|
   * Sets the link length (m).
 | 
						|
   *
 | 
						|
   * @param ilinkLen new link length
 | 
						|
   */
 | 
						|
  void setLinkLength(double ilinkLen);
 | 
						|
 | 
						|
  /**
 | 
						|
   * Sets the static friction (N*m).
 | 
						|
   *
 | 
						|
   * @param imuStatic new static friction
 | 
						|
   */
 | 
						|
  void setStaticFriction(double imuStatic);
 | 
						|
 | 
						|
  /**
 | 
						|
   * Sets the dynamic friction (N*m).
 | 
						|
   *
 | 
						|
   * @param imuDynamic new dynamic friction
 | 
						|
   */
 | 
						|
  void setDynamicFriction(double imuDynamic);
 | 
						|
 | 
						|
  /**
 | 
						|
   * Sets the timestep (sec).
 | 
						|
   *
 | 
						|
   * @param itimestep new timestep
 | 
						|
   */
 | 
						|
  void setTimestep(double itimestep);
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns the current angle (angle in rad).
 | 
						|
   *
 | 
						|
   * @return the current angle
 | 
						|
   */
 | 
						|
  double getAngle() const;
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns the current omgea (angular velocity in rad / sec).
 | 
						|
   *
 | 
						|
   * @return the current omega
 | 
						|
   */
 | 
						|
  double getOmega() const;
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns the current acceleration (angular acceleration in rad / sec^2).
 | 
						|
   *
 | 
						|
   * @return the current acceleration
 | 
						|
   */
 | 
						|
  double getAcceleration() const;
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns the maximum torque input.
 | 
						|
   *
 | 
						|
   * @return the max torque input
 | 
						|
   */
 | 
						|
  double getMaxTorque() const;
 | 
						|
 | 
						|
  protected:
 | 
						|
  double inputTorque = 0;    // N*m
 | 
						|
  double maxTorque = 0.5649; // N*m
 | 
						|
  double angle = 0;          // rad
 | 
						|
  double omega = 0;          // rad / sec
 | 
						|
  double accel = 0;          // rad / sec^2
 | 
						|
  double mass;               // kg
 | 
						|
  double linkLen;            // m
 | 
						|
  double muStatic;           // N*m
 | 
						|
  double muDynamic;          // N*m
 | 
						|
  double timestep;           // sec
 | 
						|
  double I = 0;              // moment of inertia
 | 
						|
  std::function<double(double, double, double)> torqueFunc;
 | 
						|
 | 
						|
  const double minTimestep = 0.000001; // 1 us
 | 
						|
 | 
						|
  virtual double stepImpl();
 | 
						|
};
 | 
						|
} // namespace okapi
 |