[VicPiMakers Projects] Challenge 2: final results C++ program
Mark G.
vpm at palaceofretention.ca
Sun Nov 15 11:11:29 PST 2020
Thanks Jim.
I rechecked my formulas and found an errant factor
of 2 in my calculation of the a value (not acceleration)
for the ax^2 + bx + c equation.
Re-running:
$ echo 33009 9002 11 | ../bin/cnc
Input:
RegP: 33009 bits: 1000000011110001
RegM: 9002 bits: 0010001100101010
RegS: 11 bits: 00001011
Output #1: 241 (position) bits: 11110001
Output #2: 35 (velocity) bits: 00100011
Output #3: 2 (accel.) bits: 00000010
Output #4: 10 (time) bits: 00001010
Error status:
Position error.
Velocity ok.
Acceleration error.
Time error.
Error corrected:
Output #5: 240 (position) bits: 11110000
Output #6: 35 (velocity) bits: 00100011
Output #7: 10 (accel.) bits: 00001010
Output #8: 9 (time) bits: 00001001
Error status:
Position ok.
Velocity ok.
Acceleration ok.
Time ok.
Output #9:
Travel time t: 6.93 (s)
final velocity v: 69.28 (cm/sec)
Output #10:
Testung t1 solution 1: 5.68 (s)
Invalid t2 with t1 solution 1: -2.36
trying t1 solution 2: 1.32 (s)
Valid t2 with t1 solution 2: 6.36 (s)
Solution t1: 1.32 (s)
Solution t2: 6.36 (s)
Output #11:
Solutions involving a negative amount for t2 are not
physically possible without time travel.
===========
I wrote the program in C++, using a class named PointPlotter
and a main program, just to get practice using classes in
C++.
Mark
On 2020-11-15 12:25 a.m., James Briante wrote:
> Hi Mark,
>
> Congratulations for 100% on Challenge 2 (Bonus helped!)
>
> I’ve used your times for (t_1 , t_2 ) to compute total distance covered.
>
> P = 2p_1 + p_2
>
> = at_1 ^2 + vt_2 , using your values gives
>
> = 10(1.17)^2 + 35(6.66)
>
> = 246.789, past desired position (p =240)
>
> Check your solution to the quadratic equation.
>
> Jim
>
>
>
> On Sat, Nov 14, 2020 at 9:29 PM Mark G. <vpm at palaceofretention.ca
> <mailto:vpm at palaceofretention.ca>> wrote:
>
> Hi Jim,
>
> Thanks for the corrections. Here are my updated results
> with some trial solutions for outputs 9 and 10.
> I differ in output 10.
>
> $ echo 33009 9002 11 | ../bin/cnc
> Input:
> RegP: 33009 bits: 1000000011110001
> RegM: 9002 bits: 0010001100101010
> RegS: 11 bits: 00001011
> Output #1: 241 (position) bits: 11110001
> Output #2: 35 (velocity) bits: 00100011
> Output #3: 2 (accel.) bits: 00000010
> Output #4: 10 (time) bits: 00001010
>
> Error status:
> Position error.
> Velocity ok.
> Acceleration error.
> Time error.
>
> Error corrected:
> Output #5: 240 (position) bits: 11110000
> Output #6: 35 (velocity) bits: 00100011
> Output #7: 10 (accel.) bits: 00001010
> Output #8: 9 (time) bits: 00001001
>
> Error status:
> Position ok.
> Velocity ok.
> Acceleration ok.
> Time ok.
>
> Output #9:
> Travel time t: 6.93 (s)
> final velocity v: 69.28 (cm/sec)
>
> Output #10:
> Testung t1 solution 1: 12.83 (s)
> Invalid t2 with t1 solution 1: -16.66
> trying t1 solution 2: 1.17 (s)
> Valid t2 with t1 solution 2: 6.66 (s)
>
> Solution t1: 1.17 (s)
> Solution t2: 6.66 (s)
>
> Output #11:
> Solutions involving a negative amount for t2 are not
> physically possible without time travel.
>
>
>
> On 2020-11-12 8:00 p.m., James Briante wrote:
> >
> >
> > Mark -a big thanks for pointing out the errors! v & t in the
> > Callenge2.pdf are typing errors. I should have included the actual
> > output screen (see attachment) with the other files. I've blacked
> out
> > the answer to Output #11.
> >
> > Things have been quiet on project talk re: challenge 2. Could these
> > errors be the reason?
> >
> > I don't have a read on what I should do for output #10. Should I
> provide
> > the solution to the quadratic equation?
> >
> > Jim
> >
> >
> > On Wed, Nov 11, 2020 at 5:09 PM Mark G. <vpm at palaceofretention.ca
> <mailto:vpm at palaceofretention.ca>
> > <mailto:vpm at palaceofretention.ca
> <mailto:vpm at palaceofretention.ca>>> wrote:
> >
> > Hi Jim,
> >
> > I've completed up-to output #8 of the challenge and have
> > some discrepancies with your challenge specification.
> > Specifically, velocity/acceleration error switch, differing
> > values for uncorrected time (t) and velocity (v).
> >
> > Your values:
> > Input Data: 33009,9002,11 (initial values - RegP, RegM, RegS)
> > Output #1: 241 (value of p, transferred from RegP)
> > Output #2: 186 (value of v, transferred from RegM)
> > Output #3: 10 (value of a, transferred from RegM)
> > Output #4: 220 (value of t, transferred RegM)
> >
> --------------------------------------------------------------------------------
> >
> > Output # 5 to #8 – values of p, v, a, and t with corrections
> >
> --------------------------------------------------------------------------------
> >
> > Output #5: 240 (p)
> > Output #6: 35 (v)
> > Output #7: 10 (a)
> > Output #8: 9 (t)
> >
> > My values:
> >
> > $ echo 33009 9002 11 | ../bin/cnc
> > Input:
> > RegP: 33009 bits: 1000000011110001
> > RegM: 9002 bits: 0010001100101010
> > RegS: 11 bits: 00001011
> > Output #1: 241 (position) bits: 11110001
> > Output #2: 35 (velocity) bits: 00100011
> > Output #3: 2 (accel.) bits: 00000010
> > Output #4: 10 (time) bits: 00001010
> > Position error.
> > Velocity ok.
> > Acceleration error.
> > Time error.
> > Error corrected:
> > Output #5: 240 (position) bits: 11110000
> > Output #6: 35 (velocity) bits: 00100011
> > Output #7: 10 (accel.) bits: 00001010
> > Output #8: 9 (time) bits: 00001001
> > Position ok.
> > Velocity ok.
> > Acceleration ok.
> > Time ok.
> >
> > What do you think?
> >
> > Mark
> >
> > --
> > Projects mailing list
> > Projects at vicpimakers.ca <mailto:Projects at vicpimakers.ca>
> <mailto:Projects at vicpimakers.ca <mailto:Projects at vicpimakers.ca>>
> > http://vicpimakers.ca/mailman/listinfo/projects_vicpimakers.ca
> >
> >
>
> --
> Projects mailing list
> Projects at vicpimakers.ca <mailto:Projects at vicpimakers.ca>
> http://vicpimakers.ca/mailman/listinfo/projects_vicpimakers.ca
>
>
-------------- next part --------------
#pragma once
/* Declarations for point plotter class. This mimics
* a single axis (x) CNC machine.
* Mark G. 2020-11-07
*/
#include <iostream>
#include <cstddef>
#include <cstdlib>
#include <vector>
#include <bitset>
#include <complex>
#include <cmath>
/*
* Masks for bit patterns.
*/
const unsigned short int position_mask = 0x00ff;
const unsigned short int position_shift = 0x0;
const unsigned short int direction_mask = 0x8000;
const unsigned short int velocity_mask = 0xff00;
const unsigned short int velocity_shift = 0x8;
const unsigned short int acceleration_mask = 0x00f0;
const unsigned short int acceleration_shift = 0x4;
const unsigned short int time_mask = 0x000f;
const unsigned short int time_shift = 0x0;
const unsigned char POS_ERROR {8};
const unsigned char VEL_ERROR {4};
const unsigned char ACC_ERROR {2};
const unsigned char TIME_ERROR {1};
enum directions { reverse, forward };
enum motion_representations { integer, real_number };
using namespace std::complex_literals;
struct Quadratic_tuple
{
std::complex<float> solution1 { 0.0f + 0if};
std::complex<float> solution2 { 0.0f + 0if};
};
struct timepair
{
float t1 {0.0f};
float t2 {0.0f};
};
class PointPlotter {
public:
PointPlotter() = default;
~PointPlotter() = default;
void decode_reg_p(unsigned short int p);
void decode_reg_m(unsigned short int m);
void decode_reg_s(unsigned char s);
bool pos_error() { return ((reg_s & POS_ERROR) != 0); }
bool vel_error() { return ((reg_s & VEL_ERROR) != 0); }
bool acc_error() { return ((reg_s & ACC_ERROR) != 0); }
bool time_error() { return ((reg_s & TIME_ERROR) != 0); }
void correct_errors();
void show_errors();
void set_direction();
void print_pva();
unsigned char get_position() { return position; }
unsigned char get_velocity() { return velocity; }
unsigned char get_acceleration() { return acceleration; }
unsigned char get_time() { return time; }
timepair& solve_trapezoid(timepair& t);
float solve_no_profile(float& velocity);
private:
uint16_t reg_p { 0 };
uint16_t reg_m { 0 };
unsigned char reg_s { 0 };
directions direction { directions::forward };
unsigned char position { 0 };
unsigned char velocity { 0 };
unsigned char acceleration { 0 };
unsigned char time { 0 };
float f_position {0.0};
float f_velocity {0.0};
float f_acceleration {0.0};
float f_time {0.0};
};
-------------- next part --------------
/* Definitions for point plotter class. This mimics
* a single axis (x) CNC machine.
* Mark G. 2020-11-07
*/
#include "point_plotter.hxx"
void PointPlotter::decode_reg_p(uint16_t p) {
reg_p = p;
position = (reg_p & position_mask) >> position_shift;
f_position = (float)position;
set_direction();
}
void PointPlotter::decode_reg_m(uint16_t m)
{
reg_m = m;
velocity = (reg_m & velocity_mask) >> velocity_shift;
f_velocity = (float)velocity;
acceleration = (reg_m & acceleration_mask) >> acceleration_shift;
f_acceleration = (float)acceleration;
time = (reg_m & time_mask) >> time_shift;
f_time = (float)time;
}
void PointPlotter::decode_reg_s(unsigned char s) {
reg_s = s;
}
void PointPlotter::show_errors()
{
std::cout << std::endl;
std::cout << "Error status:" << std::endl;
if (pos_error()) std::cout << "Position error." << std::endl;
else std::cout << "Position ok." << std::endl;
if (vel_error()) std::cout << "Velocity error." << std::endl;
else std::cout << "Velocity ok." << std::endl;
if (acc_error()) std::cout << "Acceleration error." << std::endl;
else std::cout << "Acceleration ok." << std::endl;
if (time_error()) std::cout << "Time error." << std::endl;
else std::cout << "Time ok." << std::endl;
std::cout << std::endl;
}
void PointPlotter::correct_errors()
{
if (pos_error()) {
position = position & ~0x01;
reg_s = reg_s & 0xF7;
f_position = (float)position;
}
if (vel_error()) {
velocity = ~velocity;
reg_s = reg_s & 0xFB;
f_velocity = (float)velocity;
}
if (acc_error()) {
acceleration = acceleration | (1<<3);
reg_s = reg_s & 0xFD;
f_acceleration = (float)acceleration;
}
if (time_error()) {
if ( (time & 0x01) ^ (time & 0x02) ) {
//std::cout << "Time: bits 1 and 0 differ (xor)" << std::endl;
if (time & 0x01) {
//std::cout << "Time: bit 0 set " << std::bitset<8>(time) << std::endl;
time = (time | 0x02) & 0xfe;
//std::cout << "Time: bit 1 and 0 swapped " << std::bitset<8>(time) << std::endl;
} else {
//std::cout << "Time: bit 1 set " << std::bitset<8>(time) << std::endl;
time = (time | 0x01) & 0xfd;
//std::cout << "Time: bit 1 and 0 swapped " << std::bitset<8>(time) << std::endl;
}
}
reg_s = reg_s & 0xFE;
f_time = (float)time;
}
}
void PointPlotter::set_direction() {
if (reg_p & direction_mask) {
direction = directions::forward;
} else {
direction = directions::reverse;
}
}
void PointPlotter::print_pva() {
std::cout << "Position: " << (int)position << "\t" << std::bitset<8>(position) << std::endl;
std::cout << "Velocity: " << (int)velocity << "\t" << std::bitset<8>(velocity) << std::endl;
std::cout << "Acceleration: " << (int)acceleration << "\t" << std::bitset<8>(acceleration) << std::endl;
std::cout << "Time: " << (int)time << "\t" << std::bitset<8>(time) << std::endl;
std::cout << std::endl;
}
timepair& PointPlotter::solve_trapezoid(timepair& t)
{
Quadratic_tuple t1;
t.t1 = NAN;
t.t2 = NAN;
float a = f_acceleration;
float b = (-2.0f)*f_velocity;
float c = (f_velocity * f_time) - f_position;
float discriminant = b*b - 4*a*c;
float part1 = (-1.0f * b) / (2.0f * a);
if (discriminant < 0.0f) {
t1.solution1 = part1 + 1if * std::sqrt(-discriminant) / (2.0f * a);
t1.solution2 = part1 - 1if * std::sqrt(-discriminant) / (2.0f * a);
} else {
t1.solution1 = part1 + std::sqrt(discriminant) / (2.0f * a);
t1.solution2 = part1 - std::sqrt(discriminant) / (2.0f * a);
}
//std::cout << "Part 1 of t1 solution (-b/2a): " << part1 << std::endl;
//std::cout << "Discriminant of t1 solutions (b^2-4ac): " << discriminant << std::endl;
if (std::imag(t1.solution1) > 0.0f) {
std::cout << "no solution" << std::endl;
std::cout << " quadratic solutions for t1 are complex numbers: " << std::endl;
std::cout << " " << t1.solution1 << std::endl;
std::cout << " " << t1.solution2 << std::endl;
} else {
std::cout << " Testung t1 solution 1: " << std::real(t1.solution1) << " (s)" << std::endl;
float t2 = f_time - 2.0f * std::real(t1.solution1);
if (t2 < 0.0f) {
std::cout << " Invalid t2 with t1 solution 1: " << t2 << std::endl;
std::cout << " trying t1 solution 2: " << std::real(t1.solution2) << " (s)" << std::endl;
t2 = f_time - 2.0f * std::real(t1.solution2);
if (t2 < 0.0f) {
std::cout << " Invalid t2 with t1 solution 2: " << t2 << " (s)" << std::endl;
} else {
std::cout << " Valid t2 with t1 solution 2: " << t2 << " (s)" << std::endl;
t.t1 = std::real(t1.solution2);
t.t2 = t2;
}
} else {
std::cout << " Valid t2 with t1 solution 1: " << t2 << " (s)" << std::endl;
t.t1 = std::real(t1.solution1);
t.t2 = t2;
}
}
std::cout << std::endl;
return t;
}
float PointPlotter::solve_no_profile(float& vel)
{
float travel_time = 0.0f;
travel_time = std::sqrt(2.0f * f_position / f_acceleration);
vel = f_acceleration * travel_time;
return travel_time;
}
-------------- next part --------------
/*
* Program to complete the second programming challenge given
* by Jim B.
* Writtem by Mark G. 2020-11-07
*/
#include <iostream>
#include <algorithm>
#include <numeric>
#include <vector>
#include <string>
#include <map>
#include <cctype>
#include <iomanip>
#include "point_plotter.hxx"
void print_output_and_number(int number) {
std::cout << "Output #" << number << ": ";
}
int main()
{
using namespace std::complex_literals;
uint16_t reg_p { 0 };
uint16_t reg_m { 0 };
uint16_t reg_s { 0 };
timepair times;
std::cin >> reg_p;
std::cin >> reg_m;
std::cin >> reg_s;
std::cout << "Input: " << std::endl;
std::cout << "RegP: " << (int)reg_p << "\t bits: " << std::bitset<16>(reg_p) << std::endl;
std::cout << "RegM: " << (int)reg_m << "\t bits: " << std::bitset<16>(reg_m) << std::endl;
std::cout << "RegS: " << (int)reg_s << "\t bits: " << std::bitset<8>(reg_s) << std::endl;
PointPlotter xaxis;
xaxis.decode_reg_p(reg_p);
xaxis.decode_reg_m(reg_m);
xaxis.decode_reg_s(reg_s);
int output_number {1};
print_output_and_number(output_number++);
std::cout << (int)xaxis.get_position() << "\t (position) " << "\t bits: " << std::bitset<8>(xaxis.get_position()) << std::endl;
print_output_and_number(output_number++);
std::cout << (int)xaxis.get_velocity() << "\t (velocity) " << "\t bits: " << std::bitset<8>(xaxis.get_velocity()) << std::endl;
print_output_and_number(output_number++);
std::cout << (int)xaxis.get_acceleration() << "\t (accel.) " << "\t bits: " << std::bitset<8>(xaxis.get_acceleration()) << std::endl;
print_output_and_number(output_number++);
std::cout << (int)xaxis.get_time() << "\t (time) " << "\t bits: " << std::bitset<8>(xaxis.get_time()) << std::endl;
xaxis.show_errors();
xaxis.correct_errors();
std::cout << "Error corrected: " << std::endl;
print_output_and_number(output_number++);
std::cout << (int)xaxis.get_position() << "\t (position) " << "\t bits: " << std::bitset<8>(xaxis.get_position()) << std::endl;
print_output_and_number(output_number++);
std::cout << (int)xaxis.get_velocity() << "\t (velocity) " << "\t bits: " << std::bitset<8>(xaxis.get_velocity()) << std::endl;
print_output_and_number(output_number++);
std::cout << (int)xaxis.get_acceleration() << "\t (accel.) " << "\t bits: " << std::bitset<8>(xaxis.get_acceleration()) << std::endl;
print_output_and_number(output_number++);
std::cout << (int)xaxis.get_time() << "\t (time) " << "\t bits: " << std::bitset<8>(xaxis.get_time()) << std::endl;
xaxis.show_errors();
//xaxis.print_pva();
std::cout << std::fixed << std::setprecision(2);
print_output_and_number(output_number++);
std::cout << std::endl;
float final_velocity {0.0f};
float travel_time = xaxis.solve_no_profile(final_velocity);
std::cout << " Travel time t: " << travel_time << " (s)" << std::endl;
std::cout << " final velocity v: " << final_velocity << " (cm/sec)" << std::endl;
std::cout << std::endl;
print_output_and_number(output_number++);
std::cout << std::endl;
times = xaxis.solve_trapezoid(times);
std::cout << " Solution t1: " << times.t1 << " (s)" << std::endl;
std::cout << " Solution t2: " << times.t2 << " (s)" << std::endl;
std::cout << std::endl;
print_output_and_number(output_number++);
std::cout << std::endl;
std::cout << "Solutions involving a negative amount for t2 are not " << std::endl << "physically possible without time travel." << std::endl;
return 0;
}
More information about the Projects
mailing list