aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin O'Connor <kevin@koconnor.net>2019-11-01 22:53:00 -0400
committerKevin O'Connor <kevin@koconnor.net>2019-11-21 13:17:45 -0500
commita28b29993ad76a1beb7be4206f62c5694ede2248 (patch)
tree3bae1e4e2a1e6a762b1748b453e9f80d8b7772e8
parentd00023f3bbdf3c1d2b63a89612c46993112c2162 (diff)
downloadkutter-a28b29993ad76a1beb7be4206f62c5694ede2248.tar.gz
kutter-a28b29993ad76a1beb7be4206f62c5694ede2248.tar.xz
kutter-a28b29993ad76a1beb7be4206f62c5694ede2248.zip
trapq: Add code to calculate definitive integral
Support calculating the definitive integral of a cartesian axis position over a time range of the movement queue. Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
-rw-r--r--klippy/chelper/trapq.c44
-rw-r--r--klippy/chelper/trapq.h8
2 files changed, 51 insertions, 1 deletions
diff --git a/klippy/chelper/trapq.c b/klippy/chelper/trapq.c
index 603ce9e2..5d5073c1 100644
--- a/klippy/chelper/trapq.c
+++ b/klippy/chelper/trapq.c
@@ -86,6 +86,50 @@ move_get_coord(struct move *m, double move_time)
.z = m->start_pos.z + m->axes_r.z * move_dist };
}
+// Helper code for integrating acceleration
+static double
+integrate_accel(struct move *m, double start, double end)
+{
+ double half_v = .5 * m->start_v, sixth_a = (1. / 3.) * m->half_accel;
+ double si = start * start * (half_v + sixth_a * start);
+ double ei = end * end * (half_v + sixth_a * end);
+ return ei - si;
+}
+
+// Calculate the definitive integral on part of a move
+static double
+move_integrate(struct move *m, int axis, double start, double end)
+{
+ if (start < 0.)
+ start = 0.;
+ if (end > m->move_t)
+ end = m->move_t;
+ double base = m->start_pos.axis[axis - 'x'] * (end - start);
+ double integral = integrate_accel(m, start, end);
+ return base + integral * m->axes_r.axis[axis - 'x'];
+}
+
+// Calculate the definitive integral for a cartesian axis
+double
+trapq_integrate(struct move *m, int axis, double start, double end)
+{
+ double res = move_integrate(m, axis, start, end);
+ // Integrate over previous moves
+ struct move *prev = m;
+ while (unlikely(start < 0.)) {
+ prev = list_prev_entry(prev, node);
+ start += prev->move_t;
+ res += move_integrate(prev, axis, start, prev->move_t);
+ }
+ // Integrate over future moves
+ while (unlikely(end > m->move_t)) {
+ end -= m->move_t;
+ m = list_next_entry(m, node);
+ res += move_integrate(m, axis, 0., end);
+ }
+ return res;
+}
+
#define NEVER_TIME 9999999999999999.9
// Allocate a new 'trapq' object
diff --git a/klippy/chelper/trapq.h b/klippy/chelper/trapq.h
index 4572ef1a..fa55faaf 100644
--- a/klippy/chelper/trapq.h
+++ b/klippy/chelper/trapq.h
@@ -4,7 +4,12 @@
#include "list.h" // list_node
struct coord {
- double x, y, z;
+ union {
+ struct {
+ double x, y, z;
+ };
+ double axis[3];
+ };
};
struct move {
@@ -27,6 +32,7 @@ void trapq_append(struct trapq *tq, double print_time
, double start_v, double cruise_v, double accel);
double move_get_distance(struct move *m, double move_time);
struct coord move_get_coord(struct move *m, double move_time);
+double trapq_integrate(struct move *m, int axis, double start, double end);
struct trapq *trapq_alloc(void);
void trapq_free(struct trapq *tq);
void trapq_check_sentinels(struct trapq *tq);