Lamp-Da 0.1
A compact lantern project
Loading...
Searching...
No Matches
particle.hpp
Go to the documentation of this file.
1
5#ifndef PARTICLE_H
6#define PARTICLE_H
7
9
13
14#include "src/system/ext/math8.h"
15#include <cstdint>
16
17namespace lampda::modes {
18
23
24static constexpr float cylinderRadius_m = LampTy::lampBodyRadius_mm / 1000.0;
25static constexpr float angularSpeedGain = 50000;
26static constexpr float linearSpeedGain = 1.0;
27static constexpr float reboundCoeff = 0.1;
28static constexpr float speedDampening = 0.92;
29
30static constexpr float maxAngularSpeed_radS = 4 * c_TWO_PI;
31static constexpr float maxVerticalSpeed_mmS = 50;
32
37{
39 Particle() : thetaSpeed_radS(0.0), zSpeed_mS(0.0), theta_rad(0.0), z_mm(0.0) {}
40
42 Particle(const utils::vec3d& positionCartesian) :
43 thetaSpeed_radS(0.0),
44 zSpeed_mS(0.0),
45 theta_rad(atan2(positionCartesian.y, positionCartesian.x)),
46 z_mm(positionCartesian.z)
47 {
49 }
50
52 Particle(const float positionTheta_rad, const float positionZ_mm) :
53 thetaSpeed_radS(0.0),
54 zSpeed_mS(0.0),
55 theta_rad(positionTheta_rad),
56 z_mm(positionZ_mm)
57 {
59 }
60
62 Particle(const Particle& other) = default;
63
70 utils::vec2d compute_speed_increment(const utils::vec3d& accelerationCartesian_m, const float deltaTime_s) const
71 {
72 // speed vector on radial (derivative of cartesian to cylinder coordinates for theta)
73 const utils::vec3d e_theta(-sin_t(theta_rad) * cylinderRadius_m, cos_t(theta_rad) * cylinderRadius_m, 0);
74 // speed vector on z (derivative of cartesian to cylinder coordinates for z)
75 const utils::vec3d e_z(0, 0, 1);
76 // ignore the radius derivative, as we want to stay on the cylinder surface
77
78 // compute the speed vector on cylinder surface
79 const utils::vec3d& tangantialVector = e_theta.multiply(accelerationCartesian_m.dot(e_theta));
80 const utils::vec3d& directVector = e_z.multiply(accelerationCartesian_m.dot(e_z));
81 const utils::vec3d& accelerationVector = tangantialVector.add(directVector);
82
83 return utils::vec2d(angularSpeedGain * accelerationVector.dot(e_theta) / static_cast<float>(cylinderRadius_m) *
84 deltaTime_s,
85 linearSpeedGain * accelerationVector.dot(e_z) * deltaTime_s);
86 }
87
94 void apply_acceleration(const utils::vec3d& accelerationCartesian_m,
95 const float deltaTime_s,
96 const bool shouldContrain = true)
97 {
98 const auto& speedIncrement = compute_speed_increment(accelerationCartesian_m, deltaTime_s);
99 // start by dampening the speed
101
102 // update speed
104 lmpd_constrain<float>(thetaSpeed_radS + speedIncrement.x, -maxAngularSpeed_radS, maxAngularSpeed_radS);
105 zSpeed_mS = lmpd_constrain<float>(zSpeed_mS + speedIncrement.y, -maxVerticalSpeed_mmS, maxVerticalSpeed_mmS);
106
107 static constexpr float angularUnit = LampTy::maxWidthFloat / c_TWO_PI;
108 static constexpr float verticalUnit = LampTy::ledStripWidth_mm * 1.5f;
109
110 // update position (limit speed to pixel unit per dt)
111 const float angularPositionIncrement =
112 lmpd_constrain<float>(thetaSpeed_radS * deltaTime_s, -angularUnit, angularUnit);
113 const float verticalPositionIncrement =
114 lmpd_constrain<float>(zSpeed_mS * deltaTime_s, -verticalUnit, verticalUnit) * 1000.0;
115
116 // update particle position
117 z_mm += verticalPositionIncrement;
118 theta_rad += angularPositionIncrement;
119
120 // limit the derivation of the angle
122
123 // constrain to the lamp body
124 if (shouldContrain)
126 else
128 }
129
136 Particle simulate_after_acceleration(const utils::vec3d& accelerationCartesian_m,
137 const float deltaTime_s,
138 const bool shouldContrain = true) const
139 {
140 Particle simulated(*this);
141 simulated.apply_acceleration(accelerationCartesian_m, deltaTime_s, shouldContrain);
142 return simulated;
143 }
144
149 {
151
152 // coordinates go from 0 to -max
153 if (z_mm > 0)
154 {
155 z_mm = 0;
158 }
159
161 {
165 }
166
167 // handle the real limits (led strip do not start and end at zero depth)
169 {
170 // we are too high above the first led
171 if (z_mm >= 0)
172 {
173 // go one unit lower
176 }
177 else
178 {
179 // go one unit above
182 }
183 // udpate index
185 }
186 }
187
189 void dampen_speed(const float dampenFactor)
190 {
191 thetaSpeed_radS *= dampenFactor;
192 zSpeed_mS *= dampenFactor;
193 }
194
196 uint16_t to_lamp_index() const { return to_led_index(theta_rad, z_mm); }
199
201 float zSpeed_mS;
202
203 float theta_rad;
204 float z_mm;
205
208};
209
210} // namespace lampda::modes
211
212#endif
Contains basic interface types to implement custom user modes.
Definition: control_fixed_modes.hpp:12
static constexpr float angularSpeedGain
this gain compensate the angular acceleration for better display
Definition: particle.hpp:25
static constexpr float maxVerticalSpeed_mmS
max vertical speed in mm/S
Definition: particle.hpp:31
static constexpr uint16_t to_led_index(const float angle_rad, const float z)
convert a lamp coordinate to a led index
Definition: lamp_type.hpp:1208
static constexpr float speedDampening
low speed dampening [0-0.99] at every steps (viscosity)
Definition: particle.hpp:28
static constexpr int16_t to_led_index_no_bounds(const float angle_rad, const float z)
convert a lamp coordinate to a led index, the result can be an index out of the lamp body
Definition: lamp_type.hpp:1243
static constexpr float linearSpeedGain
gain for the linear speeds
Definition: particle.hpp:26
static constexpr bool is_led_index_valid(const int16_t ledIndex)
True if the given strip index is a valid one.
Definition: lamp_type.hpp:1189
static constexpr float maxAngularSpeed_radS
max angular speed in radians/s
Definition: particle.hpp:30
static constexpr float cylinderRadius_m
radius of the cylinder, in meters
Definition: particle.hpp:24
static constexpr float reboundCoeff
low rebound [0 - 1] on walls
Definition: particle.hpp:27
static constexpr float wrap_angle(const float angle_rad)
Wrap an angle in radians between 0 and 2*PI.
Definition: utils.h:115
static constexpr float c_TWO_PI
2*PI constant
Definition: constants.h:21
Define a particle in 3D space. it has a position and speed.
Definition: particle.hpp:37
Particle(const utils::vec3d &positionCartesian)
Construct a Particle from a 3D cartesian position.
Definition: particle.hpp:42
float theta_rad
position, in radians
Definition: particle.hpp:203
void apply_acceleration(const utils::vec3d &accelerationCartesian_m, const float deltaTime_s, const bool shouldContrain=true)
apply a cartesian acceleration to this particulate
Definition: particle.hpp:94
utils::vec2d compute_speed_increment(const utils::vec3d &accelerationCartesian_m, const float deltaTime_s) const
Compute the speed increment in the constraint lamp body.
Definition: particle.hpp:70
uint16_t to_lamp_index() const
Convert this particle coordinates to a constraint lamp index.
Definition: particle.hpp:196
int16_t _savedLampIndex
optimization
Definition: particle.hpp:207
int16_t to_lamp_index_no_bounds() const
Convert this particle coordinates to an unconstraint lamp index.
Definition: particle.hpp:198
Particle()
Default particle init.
Definition: particle.hpp:39
Particle simulate_after_acceleration(const utils::vec3d &accelerationCartesian_m, const float deltaTime_s, const bool shouldContrain=true) const
Simulate this particle movement as a new particle.
Definition: particle.hpp:136
float thetaSpeed_radS
angular speed, in radian/seconds
Definition: particle.hpp:200
Particle(const Particle &other)=default
Copy constructor for a particle.
float zSpeed_mS
linear speed, in meter/seconds
Definition: particle.hpp:201
void constraint_into_lamp_body()
Contrain the particle movement to the cylinder, limiting the movement at the extremities.
Definition: particle.hpp:148
float z_mm
height, in millimeters.
Definition: particle.hpp:204
void dampen_speed(const float dampenFactor)
Bleed off some speed. Simulate a dampening factor (like friction loss)
Definition: particle.hpp:189
Particle(const float positionTheta_rad, const float positionZ_mm)
Construct a particle from an angle and height.
Definition: particle.hpp:52
Main interface between the user and the hardware of the lamp.
Definition: lamp_type.hpp:114
static constexpr float lampHeight_mm
Computation of the lamp height.
Definition: lamp_type.hpp:437
static constexpr float maxWidthFloat
Width as a precise floating point number, equal to stripXCoordinates.
Definition: lamp_type.hpp:369
static constexpr float ledStripWidth_mm
real size of the led strip in use
Definition: lamp_type.hpp:423
static constexpr float lampBodyRadius_mm
real radius of the lamp body
Definition: lamp_type.hpp:420
2d vector in any space
Definition: vector_math.h:15
3d vector in any space
Definition: vector_math.h:54
vec3d add(const vec3d &other) const
Coefficient wise addition.
Definition: vector_math.h:71
float dot(const vec3d &other) const
Dot product in 3D, representing the arcos of the angle between this vector and another.
Definition: vector_math.h:65
vec3d multiply(const vec3d &other) const
Coefficient wise multiplication.
Definition: vector_math.h:67
Define the system hardware constants.
User defined constants, relative to specific lamp types.
Define useful functions.
Define vectors and rotation matrices, and the possibility to rotate vectors.