Unverified Commit 99281427 authored by Jeff Niu's avatar Jeff Niu Committed by GitHub

Merge pull request #57 from Mogball/jeff/friction_fix

Fixed friction calculation and added stats display
parents ba9d7972 39dd5449
#include <QPainter>
#include <chrono>
#include "arrow.h"
#include "renderscene.h"
#include "statsdisplay.h"
#include "../gui/mainwindow.h"
#include "arrow.h"
RenderScene::RenderScene(std::shared_ptr<Simulator> simulator, QWidget *parent)
: QOpenGLWidget(parent),
m_simulator(std::move(simulator)),
m_sam(this, MU_sf, 1e-3f, 0.01f) {
m_sam(this, MU_SF, 1e-3f, 0.01f) {
m_elapsed = 0;
setAutoFillBackground(false);
......@@ -44,6 +45,7 @@ void RenderScene::animate() {
}
void RenderScene::startRender() {
m_sam.reset();
if (!m_timer.isActive()) {
m_timer.start();
}
......@@ -64,6 +66,10 @@ const std::vector<Solenoid> *RenderScene::solenoids() const {
return &m_solenoids;
}
const SAMRobot *RenderScene::sam() const {
return &m_sam;
}
void RenderScene::paintEvent(QPaintEvent *event) {
long long int timeMillis = std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::system_clock::now().time_since_epoch()
......@@ -80,5 +86,7 @@ void RenderScene::paintEvent(QPaintEvent *event) {
m_sam.draw(&painter, event, deltaMillis, 2000);
Arrow samForce(this, m_sam.pos(), m_sam.mag());
samForce.draw(&painter, event, deltaMillis, 2000);
StatsDisplay statsDisplay(this);
statsDisplay.draw(&painter, event, deltaMillis, 2000);
painter.end();
}
......@@ -62,6 +62,11 @@ public:
*/
const std::vector<Solenoid> *solenoids() const override;
/**
* @return a pointer to the Sam instance.
*/
const SAMRobot *sam() const override;
/**
* Start the ticker.
*/
......@@ -93,7 +98,7 @@ private:
/**
* Object representing the location of SAM.
*/
Sam m_sam;
SAMRobot m_sam;
};
......
......@@ -2,15 +2,16 @@
#define MINOTAUR_CPP_RENDERSCENEBASE_H
// Magnetic permeability of free space
#define MU_0f ((float) M_PI * 4e-7f)
#define MU_0F ((float) M_PI * 4e-7f)
// Coefficient of static friction
#define MU_sf 15.0f
#define MU_SF 1.0f
// Gravitational field strength
#define gf 9.809f
#define G_FIELD 9.809f
#include "drawable.h"
class Solenoid;
class SAMRobot;
/**
* Base render scene referenced by Drawables to
......@@ -22,6 +23,7 @@ public:
virtual vector2f center() const = 0;
virtual const std::vector<Solenoid> *solenoids() const = 0;
virtual const SAMRobot *sam() const = 0;
};
#endif //MINOTAUR_CPP_RENDERSCENEBASE_H
#include "sam.h"
#include "solenoid.h"
Sam::Sam(RenderSceneBase *scene, float mu_s, float mass, float length)
SAMRobot::SAMRobot(RenderSceneBase *scene, float mu_s, float mass, float length)
: m_renderScene(scene),
m_fric(mu_s),
m_mass(mass),
......@@ -10,7 +10,7 @@ Sam::Sam(RenderSceneBase *scene, float mu_s, float mass, float length)
m_vel(0, 0) {
}
void Sam::draw(QPainter *painter, QPaintEvent *, int elapsed, float scale) {
void SAMRobot::draw(QPainter *painter, QPaintEvent *, int elapsed, float scale) {
// Update phase
float dt = elapsed / 1000.0f;
const std::vector<Solenoid> *solenoids = m_renderScene->solenoids();
......@@ -19,9 +19,9 @@ void Sam::draw(QPainter *painter, QPaintEvent *, int elapsed, float scale) {
for (auto &solenoid : *solenoids) {
m_mag += solenoid.fieldAt(m_pos);
}
float vel = sqrtf(m_vel.x() * m_vel.x() + m_vel.y() + m_vel.y());
if (vel > 1e-6) {
float sfric = gf * m_mass * m_fric;
float vel = hypotf(m_vel.x(), m_vel.y());
if (vel > 0) {
float sfric = G_FIELD * m_mass * m_fric;
vector2f vfric(-sfric * m_vel.x() / vel, -sfric * m_vel.y() / vel);
bool xdir = m_vel.x() > 0;
bool ydir = m_vel.y() > 0;
......@@ -55,17 +55,28 @@ void Sam::draw(QPainter *painter, QPaintEvent *, int elapsed, float scale) {
painter->drawPolygon(vertices, 4);
}
const typename Sam::vector2f &
Sam::pos() const {
const typename SAMRobot::vector2f &
SAMRobot::pos() const {
return m_pos;
}
const typename Sam::vector2f &
Sam::mag() const {
const typename SAMRobot::vector2f &
SAMRobot::vel() const {
return m_vel;
}
const typename SAMRobot::vector2f &
SAMRobot::mag() const {
return m_mag;
}
void Sam::stop() {
void SAMRobot::stop() {
m_vel.setX(0);
m_vel.setY(0);
}
void SAMRobot::reset() {
m_pos.setX(0);
m_pos.setY(0);
stop();
}
......@@ -8,7 +8,7 @@
* This class represents SAM, a robot with an orientation and
* position in the field.
*/
class Sam : public Drawable {
class SAMRobot : public Drawable {
public:
/**
* Create an instance of SAM.
......@@ -18,7 +18,7 @@ public:
* @param mass the mass of SAM
* @param length the length of SAM (in meters), which is shaped as a square
*/
explicit Sam(RenderSceneBase *scene, float mu_s, float mass, float length);
explicit SAMRobot(RenderSceneBase *scene, float mu_s, float mass, float length);
/**
* Draw SAM.
......@@ -34,11 +34,21 @@ public:
*/
void stop();
/**
* Reset SAM's position.
*/
void reset();
/**
* @return SAM's current position
*/
const vector2f &pos() const;
/**
* @return SAM's current velocity
*/
const vector2f &vel() const;
/**
* @return the current magnetic field magnitude on SAM
*/
......
......@@ -50,7 +50,7 @@ void Solenoid::draw(QPainter *painter, QPaintEvent *, int, float scale) {
typename Solenoid::vector2f
Solenoid::fieldAt(const vector2f &Q) const {
vector2f Qp = rotate(translate(Q, m_pos), -m_theta);
float k = MU_0f * m_mu * m_I * m_N * powf(m_radius, 2.0f) / 4.0f;
float k = MU_0F * m_mu * m_I * m_N * powf(m_radius, 2.0f) / 4.0f;
float l2 = m_len / 2.0f;
float yp1 = Qp.y() - l2;
float yp2 = Qp.y() + l2;
......
#include <QPainter>
#include "statsdisplay.h"
#include "sam.h"
StatsDisplay::StatsDisplay(RenderSceneBase *render_scene)
: m_render_scene(render_scene) {}
void StatsDisplay::draw(QPainter *painter, QPaintEvent *, int, float) {
QString pos, vel, mag;
const SAMRobot *sam = m_render_scene->sam();
char format[] = "(%.3g, %.3g)";
pos.sprintf(format, sam->pos().x(), sam->pos().y());
vel.sprintf(format, sam->vel().x(), sam->vel().y());
mag.sprintf(format, sam->mag().x(), sam->mag().y());
painter->setPen(Qt::white);
painter->drawText(5, 15, "Position");
painter->drawText(5, 35, "Velocity");
painter->drawText(5, 55, "Magnetic");
painter->drawText(65, 15, pos);
painter->drawText(65, 35, vel);
painter->drawText(65, 55, mag);
}
#ifndef MINOTAUR_CPP_STATSDISPLAY_H
#define MINOTAUR_CPP_STATSDISPLAY_H
#include "drawable.h"
#include "renderscenebase.h"
class StatsDisplay : public Drawable {
public:
explicit StatsDisplay(RenderSceneBase *render_scene);
void draw(QPainter *painter, QPaintEvent *, int, float) override;
private:
RenderSceneBase *m_render_scene;
};
#endif //MINOTAUR_CPP_STATSDISPLAY_H
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment