Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
C
CA-Framework
Manage
Activity
Members
Labels
Plan
Issues
0
Issue boards
Milestones
Wiki
Code
Merge requests
0
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package Registry
Operate
Environments
Terraform modules
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Courses
CA-Framework
Commits
a743ae3f
Commit
a743ae3f
authored
2 years ago
by
DALAB\sjtud
Browse files
Options
Downloads
Patches
Plain Diff
initialize
parent
9814ef6b
Branches
Branches containing commit
No related merge requests found
Changes
63
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
include/RigidObject.h
+67
-0
67 additions, 0 deletions
include/RigidObject.h
include/Simulation.h
+81
-0
81 additions, 0 deletions
include/Simulation.h
include/Simulator.h
+263
-0
263 additions, 0 deletions
include/Simulator.h
with
411 additions
and
0 deletions
include/RigidObject.h
0 → 100644
+
67
−
0
View file @
a743ae3f
#ifndef RIGIDOBJECT_H
#define RIGIDOBJECT_H
#include
"BaseObject.h"
/*
* Base class representing a simple rigid object.
*/
class
RigidObject
:
public
BaseObject
{
public:
RigidObject
()
{}
RigidObject
(
const
std
::
string
&
mesh_path
,
const
ObjType
t
=
ObjType
::
DYNAMIC
);
virtual
~
RigidObject
()
{}
void
applyForceToCOM
(
const
Eigen
::
Vector3d
&
f
);
/*
* Apply force f at point p.
*/
void
applyForce
(
const
Eigen
::
Vector3d
&
f
,
const
Eigen
::
Vector3d
&
p
);
void
applyTorque
(
const
Eigen
::
Vector3d
&
t
);
void
printDebug
(
const
std
::
string
&
message
=
""
)
const
;
#pragma region GettersAndSetters
virtual
void
setType
(
ObjType
t
)
override
;
void
setMass
(
double
m
);
void
setInertia
(
const
Eigen
::
Matrix3d
&
I
);
void
setLinearMomentum
(
const
Eigen
::
Vector3d
&
p
);
void
setAngularMomentum
(
const
Eigen
::
Vector3d
&
l
);
void
setLinearVelocity
(
const
Eigen
::
Vector3d
&
v
);
void
setAngularVelocity
(
const
Eigen
::
Vector3d
&
w
);
void
setForce
(
const
Eigen
::
Vector3d
&
f
);
void
setTorque
(
const
Eigen
::
Vector3d
&
t
);
void
resetForce
();
void
resetTorque
();
double
getMass
()
const
;
double
getMassInv
()
const
;
Eigen
::
Matrix3d
getInertia
()
const
;
Eigen
::
Matrix3d
getInertiaInv
()
const
;
Eigen
::
Matrix3d
getInertiaInvWorld
()
const
;
Eigen
::
Matrix3d
getInertiaWorld
()
const
;
Eigen
::
Vector3d
getLinearMomentum
()
const
;
Eigen
::
Vector3d
getAngularMomentum
()
const
;
Eigen
::
Vector3d
getLinearVelocity
()
const
;
Eigen
::
Vector3d
getVelocity
(
const
Eigen
::
Vector3d
&
point
)
const
;
Eigen
::
Vector3d
getAngularVelocity
()
const
;
Eigen
::
Vector3d
getForce
()
const
;
Eigen
::
Vector3d
getTorque
()
const
;
#pragma endregion GettersAndSetters
protected
:
virtual
void
resetMembers
()
override
;
private
:
double
m_mass
;
// Body mass
double
m_massInv
;
// Inverted mass
Eigen
::
Matrix3d
m_inertia
;
// Intertial Tensor (initially set to cube)
Eigen
::
Matrix3d
m_inertiaInv
;
// Inverse
Eigen
::
Vector3d
m_v
;
// Linear velocity
Eigen
::
Vector3d
m_w
;
// Angular velocity
Eigen
::
Vector3d
m_force
;
// Force on body
Eigen
::
Vector3d
m_torque
;
// Torque on body
};
#endif
\ No newline at end of file
This diff is collapsed.
Click to expand it.
include/Simulation.h
0 → 100644
+
81
−
0
View file @
a743ae3f
#ifndef SIMULATION_H
#define SIMULATION_H
#include
<igl/opengl/glfw/Viewer.h>
#include
"RigidObject.h"
/*
* Base class for different kinds of simulation. Provides methods for
* controlling the simulation and rendering it in a Gui.
*/
class
Simulation
{
public:
Simulation
()
{}
virtual
~
Simulation
()
{}
/*
* Initialize the necessary class variables at the beginning of the
* simulation.
*/
virtual
void
init
()
{}
/*
* Reset class variables to reset the simulation.
*/
void
reset
()
{
m_time
=
0.0
;
m_step
=
0
;
resetMembers
();
}
/*
* Update the rendering data structures. This method will be called in
* alternation with advance(). This method blocks rendering in the
* viewer, so do *not* do extensive computation here (leave it to
* advance()).
*/
virtual
void
updateRenderGeometry
()
=
0
;
/*
* Performs one simulation step of length m_dt. This method *must* be
* thread-safe with respect to renderRenderGeometry() (easiest is to not
* touch any rendering data structures at all). You have to update the time
* variables at the end of each step if they are necessary for your
* simulation.
* Return true means the simulation is finished.
*/
virtual
bool
advance
()
=
0
;
/*
* Perform any actual rendering here. This method *must* be thread-safe with
* respect to advance(). This method runs in the same thread as the
* viewer and blocks user IO, so there really should not be any extensive
* computation here or the UI will lag/become unresponsive (the whole reason
* the simulation itself is in its own thread.)
*/
virtual
void
renderRenderGeometry
(
igl
::
opengl
::
glfw
::
Viewer
&
viewer
)
=
0
;
void
setTimestep
(
double
t
)
{
m_dt
=
t
;
}
double
getTime
()
const
{
return
m_time
;
}
unsigned
long
getStep
()
const
{
return
m_step
;
}
std
::
vector
<
RigidObject
>
&
getObjects
()
{
return
m_objects
;
}
protected
:
/*
* Reset class variables specific to a certain simulation. Is called by
* Simulation::reset().
*/
virtual
void
resetMembers
()
=
0
;
std
::
vector
<
RigidObject
>
m_objects
;
// vector of all objects in the simulation
double
m_dt
=
0.0
;
// length of timestep
double
m_time
=
0.0
;
// current time
unsigned
long
m_step
=
0
;
// number of performed steps in simulation
};
#endif
\ No newline at end of file
This diff is collapsed.
Click to expand it.
include/Simulator.h
0 → 100644
+
263
−
0
View file @
a743ae3f
#ifndef SIMULATOR_H
#define SIMULATOR_H
#include
"Simulation.h"
#include
<igl/opengl/glfw/Viewer.h>
#include
<igl/opengl/glfw/imgui/ImGuiMenu.h>
#include
<mutex>
#include
<queue>
#include
<thread>
using
namespace
std
::
chrono
;
/*
* Class for running a simulation (see Simulation.h) on a separate thread.
* Performs stepping through simulation (including pausing/resuming/killing) and
* updating the rendering in the viewer.
*/
class
Simulator
{
public:
Simulator
(
Simulation
*
sim
)
:
p_simulator_thread
(
NULL
),
p_simulation
(
sim
),
m_please_pause
(
false
),
m_please_die
(
false
),
m_running
(
false
),
m_started
(
false
),
m_single_iteration
(
false
),
m_recording
(
false
)
{}
virtual
~
Simulator
()
{
killSimulatorThread
();
delete
p_simulation
;
p_simulation
=
NULL
;
}
/*
* Runs the simulation, if it has been paused (or never started).
*/
void
run
(
bool
single
=
false
)
{
m_status_mutex
.
lock
();
if
(
!
m_started
)
{
p_simulation
->
reset
();
m_started
=
true
;
if
(
single
)
{
std
::
cout
<<
"Single step"
<<
std
::
endl
;
}
else
{
std
::
cout
<<
"Start simulation"
<<
std
::
endl
;
}
}
else
if
(
m_please_pause
)
{
if
(
single
)
{
std
::
cout
<<
"Single step"
<<
std
::
endl
;
}
else
{
std
::
cout
<<
"Resume simulation"
<<
std
::
endl
;
}
}
if
(
m_please_pause
)
{
m_single_iteration
=
single
;
}
if
(
!
single
)
{
m_please_pause
=
false
;
}
m_status_mutex
.
unlock
();
}
/*
* Resets the p_simulation (and leaves it in a paused state; call run() to
* start it).
*/
void
reset
()
{
killSimulatorThread
();
if
(
m_started
)
{
std
::
cout
<<
"Reset simulation"
<<
std
::
endl
;
}
m_please_die
=
m_running
=
m_started
=
false
;
m_please_pause
=
true
;
clearRecords
();
setRecording
(
m_recording
);
p_simulation
->
reset
();
p_simulation
->
updateRenderGeometry
();
p_simulator_thread
=
new
std
::
thread
(
&
Simulator
::
runSimThread
,
this
);
}
/*
* Pause a m_running p_simulation. The p_simulation will pause at the end of
* its current "step"; this method will not interrupt simulateOneStep
* mid-processing.
*/
void
pause
()
{
m_status_mutex
.
lock
();
m_please_pause
=
true
;
m_status_mutex
.
unlock
();
std
::
cout
<<
"Pause simulation"
<<
std
::
endl
;
}
bool
isPaused
()
{
bool
ret
=
false
;
m_status_mutex
.
lock
();
if
(
m_running
&&
m_please_pause
)
ret
=
true
;
m_status_mutex
.
unlock
();
return
ret
;
}
bool
hasStarted
()
const
{
return
m_started
;
}
void
render
(
igl
::
opengl
::
glfw
::
Viewer
&
viewer
)
{
m_render_mutex
.
lock
();
p_simulation
->
renderRenderGeometry
(
viewer
);
m_render_mutex
.
unlock
();
}
double
getDuration
()
const
{
return
duration_cast
<
microseconds
>
(
m_duration
).
count
()
*
0.001
;
}
double
getSimulationTime
()
const
{
return
p_simulation
->
getTime
();
}
unsigned
long
getSimulationStep
()
const
{
return
p_simulation
->
getStep
();
}
void
setSimulationSpeed
(
int
speed
)
{
m_maxTimePerStep
=
std
::
round
(
1000
/
speed
);
}
// set maximum number of timesteps after which the simulation will stop, -1
// for infinite simulation
void
setMaxSteps
(
int
n
=
-
1
)
{
m_maxSteps
=
n
;
}
void
clearRecords
()
{
for
(
size_t
i
=
0
;
i
<
m_record
.
size
();
i
++
)
{
m_record
[
i
]
=
std
::
queue
<
std
::
pair
<
Eigen
::
MatrixXd
,
Eigen
::
MatrixXi
>>
();
}
}
void
setRecording
(
bool
r
)
{
if
(
r
&&
m_record
.
size
()
==
0
)
{
m_record
.
resize
(
p_simulation
->
getObjects
().
size
());
}
else
{
clearRecords
();
}
m_recording
=
r
;
}
bool
isRecording
()
const
{
return
m_recording
;
}
void
setNumRecords
(
int
n
)
{
m_numRecords
=
n
;
}
std
::
vector
<
std
::
queue
<
std
::
pair
<
Eigen
::
MatrixXd
,
Eigen
::
MatrixXi
>>>
&
getRecords
()
{
return
m_record
;
}
protected
:
void
storeRecord
()
{
auto
os
=
p_simulation
->
getObjects
();
Eigen
::
MatrixXd
V
;
Eigen
::
MatrixXi
F
;
for
(
size_t
i
=
0
;
i
<
os
.
size
();
i
++
)
{
os
[
i
].
getMesh
(
V
,
F
);
m_record
[
i
].
push
(
std
::
make_pair
(
V
,
F
));
while
(
m_record
[
i
].
size
()
>
(
size_t
)
m_numRecords
)
{
m_record
[
i
].
pop
();
}
}
}
void
runSimThread
()
{
m_status_mutex
.
lock
();
m_running
=
true
;
m_status_mutex
.
unlock
();
bool
done
=
false
;
while
(
!
done
)
{
m_status_mutex
.
lock
();
bool
pausenow
=
m_please_pause
;
bool
single
=
m_single_iteration
;
m_status_mutex
.
unlock
();
if
(
pausenow
&&
!
single
)
{
// don't use to much CPU time
std
::
this_thread
::
sleep_for
(
milliseconds
(
10
));
}
else
{
if
(
m_maxSteps
>=
0
&&
m_maxSteps
<=
p_simulation
->
getStep
())
{
pause
();
continue
;
}
// time execution of one loop (advance + rendering)
high_resolution_clock
::
time_point
start
=
high_resolution_clock
::
now
();
done
=
p_simulation
->
advance
();
if
(
m_recording
)
{
storeRecord
();
}
m_render_mutex
.
lock
();
p_simulation
->
updateRenderGeometry
();
m_render_mutex
.
unlock
();
high_resolution_clock
::
time_point
end
=
high_resolution_clock
::
now
();
m_duration
=
end
-
start
;
// sleep such that simulation runs at the set iterations per
// second
milliseconds
sleepTime
=
milliseconds
(
m_maxTimePerStep
)
-
duration_cast
<
milliseconds
>
(
m_duration
);
std
::
this_thread
::
sleep_for
(
sleepTime
);
}
m_status_mutex
.
lock
();
if
(
single
)
m_single_iteration
=
false
;
if
(
m_please_die
)
done
=
true
;
m_status_mutex
.
unlock
();
}
m_status_mutex
.
lock
();
m_running
=
false
;
m_status_mutex
.
unlock
();
}
void
killSimulatorThread
()
{
if
(
p_simulator_thread
)
{
m_status_mutex
.
lock
();
m_please_die
=
true
;
m_status_mutex
.
unlock
();
p_simulator_thread
->
join
();
delete
p_simulator_thread
;
p_simulator_thread
=
NULL
;
}
}
std
::
thread
*
p_simulator_thread
;
Simulation
*
p_simulation
;
duration
<
double
>
m_duration
;
bool
m_please_pause
;
bool
m_please_die
;
bool
m_running
;
bool
m_started
;
bool
m_single_iteration
;
int
m_maxTimePerStep
;
int
m_maxSteps
=
-
1
;
// max number of steps to perform, -1 for infinite
std
::
mutex
m_render_mutex
;
std
::
mutex
m_status_mutex
;
bool
m_recording
;
int
m_numRecords
;
std
::
vector
<
std
::
queue
<
std
::
pair
<
Eigen
::
MatrixXd
,
Eigen
::
MatrixXi
>>>
m_record
;
// one queue of (vertices, faces)-pairs for every object
};
#endif
\ No newline at end of file
This diff is collapsed.
Click to expand it.
Prev
1
2
3
4
Next
Preview
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment