c++ 2D servos robot arm inverse kinematics - c++

I am currently trying to write code to instruct a robot arm (2 servos motors, 3 sticks) to write out words and am having trouble getting it right. At the moment I am just trying to get it to move to a vector. I think that the inverse kinematics part is correct but all I'm getting is a twitch from one of the motors (if I'm lucky). A Nucleo- F411RE board is being used and I'm using the mbed developer.
#include "mbed.h"
#include "Servo.h"
#include "math.h"
Servo servo1(PA_8), servo2(PA_9);
float len1 = 9.0;
float len2 = 7.5;
double pi = 3.1415926535897;
int lawOfCosines (float a, float b, float c )
{
return acos((a*a + b*b - c*c) / (2 * a * b));
}
int distance(float x, float y) {
return sqrt(x*x + y*y);
}
int deg(float rad) {
return rad * 180 / pi;
}
int main() {
//fmt.Println("Lets do some tests. First move to (5,5):");
float x = 5.0;
float y = 5.0;
float dist = distance(x, y);
float D1 = atan2(y, x);
float D2 = lawOfCosines(dist, len1, len2);
float A1 = D1 + D2;
float A2 = lawOfCosines(len1, len2, dist);
float m1 = A1 * (100/90);
float m2 = A2 * (100/90);
for(int i=0; i<m1; i++) {
servo2 = i/100.0;
wait(0.01);
}
for(int i=0; i<m2; i++) {
servo1 = i/100.0;
wait(0.01);
}
}
`}
Any help to where I'm going wrong is greatly appreciated

Related

C++ compiles and runs fine but I can't generate any types of C++ outputs after certain point in the code

The code starts with declaring various arrays with a size that is pre-calculated, and will be used in the rest of the program. However, after a certain point in the list of declarations, C++ will fail to generate any output even after a successful compilation. After the comment in the middle of the code, no outputs can be generated. I have tried simple outputs like "cout" and writing in a file.
Edit: I have added a sample output written by one of the answers to demonstrate. The program just runs and does not generate anything. This is the terminal output:
"
PS C:\Users\umroot.COLLAR\projects\CrackHole> g++ .\Peridynamics.cpp -o peri
PS C:\Users\umroot.COLLAR\projects\CrackHole> .\peri.exe
PS C:\Users\umroot.COLLAR\projects\CrackHole>
#include <math.h>
#include <iostream>
#include <vector>
#include <string>
#include <conio.h>
// #include "Ellipse.h"
#include <fstream>
using namespace std;
int main () {
float length = 0.5;
float width = 0.5;
float radiusMajor = 0.05;
float radiusMinor = 0.05;
double ellipseCurvature = radiusMinor * radiusMinor / radiusMajor;
float radiusPath = 0.08;
int dt = 1;
const double ELASTIC_MODULUS = 200e9;
const float POISSON_RATIO = 0.3;
const int NumofDiv_x = 100;
const int NumofDiv_y = 100;
int timeInterval = 2500;
const double appliedPressure = 500e7;
int initialTotalNumMatPoint = NumofDiv_x * NumofDiv_y;
int maxFam = 200;
float dx = length / NumofDiv_x;
float delta = 3.015 * dx;
float thick = dx;
float volCorrRadius = dx / 2;
const double SHEAR_MODULUS = ELASTIC_MODULUS / (2 * (1 + POISSON_RATIO));
const double BULK_MODULUS = ELASTIC_MODULUS / (2 * (1 - POISSON_RATIO));
const double ALPHA = 0.5 * (BULK_MODULUS - 2 * SHEAR_MODULUS);
float area = dx * dx;
float volume = area * thick;
const float BCD = 2 / (M_PI * thick * pow(delta, 4));
int temp = floor(9 * M_PI * initialTotalNumMatPoint);
float nodeFam[100000][3] = {0.0};
int nnum = 0;
float coord_excess[initialTotalNumMatPoint][2] = {0.0};
int path_horizontal[NumofDiv_x] = {0};
// Ellipse centerHole(0, 0, radiusMajor, radiusMinor);
// Ellipse leftTip((-1) * radiusMajor, 0, 0.005, 0.005);
// Ellipse rightTip(radiusMajor, 0, 0.005, 0.005);
float coordx = 0.0;
float coordy = 0.0;
int counter = 0;
for (int i = 0; i < NumofDiv_x; i++) {
for (int j = 0; j < NumofDiv_y; j++) {
coordx = (length / 2) * (-1) + (dx / 2) + i * dx;
coordy = (width / 2) * (-1) + (dx/2) + j * dx;
// if (centerHole.InEllipse(coordx, coordy)){
// continue;
// }
if (abs(coordy) <= dx && coordx >= 0) {
path_horizontal[counter] = nnum;
counter++;
}
coord_excess[nnum][0] = coordx;
coord_excess[nnum][1] = coordy;
nnum++;
}
}
int totalNumMatPoint = nnum;
float coord[totalNumMatPoint][2] = {0.0};
for (int j = 0; j < 2; j++ ) {
for (int i = 0; i < totalNumMatPoint; i++) {
coord[i][j] = coord_excess[i][j];
}
}
int numFam[totalNumMatPoint] = {0};
int pointFam[totalNumMatPoint] = {0};
float PDForce[totalNumMatPoint][2] = {0.0};
float bodyForce[totalNumMatPoint][2] = {0.0};
float PDforceold[totalNumMatPoint][2] = {0.0};
float PD_SED_Distortion[totalNumMatPoint][2] = {0.0};
float surCorrFactorDilatation[totalNumMatPoint][2] = {0.0};
float surCorrFactorDistorsion[totalNumMatPoint][2] = {0.0};
float disp[totalNumMatPoint][2] = {0.0};
float totalDisp[totalNumMatPoint][2] = {0.0};
float vel[totalNumMatPoint][2] = {0.0};
// AFTER THIS POINT DOWNWARDS, NO OUTPUTS WILL BE GENERATED
float velhalfold[totalNumMatPoint][2] = {0.0};
float velhalf[totalNumMatPoint][2] = {0.0};
float massvec[totalNumMatPoint][2] = {0.0};
float PD_SED_Dilatation[totalNumMatPoint][2] = {0.0};
float PD_SED_Dilatation_Fixed[totalNumMatPoint][2] = {0.0};
int checkTime[timeInterval] = {0};
float steadyCheck_x[timeInterval] = {0.0};
float steadyCheck_y[timeInterval] = {0.0};
float relPositionVector = 0.0;
for (int j = 0; j < 2; j++ ) {
for (int i = 0; i < totalNumMatPoint; i++) {
coord[i][j] = coord_excess[i][j];
std::cout << coord[i][j] << std::endl;
}
}
Your code, as is, is not "outputting" anything. I compiled and ran your code and added std::cout statements below and above your comment "AFTER THIS POINT DOWNWARDS, NO OUTPUTS WILL BE GENERATED". This successfully writes to stdout.
If, for example, you wanted to output all the values in the coords array you could do something like this while you are building it:
for (int j = 0; j < 2; j++ ) {
for (int i = 0; i < totalNumMatPoint; i++) {
coord[i][j] = coord_excess[i][j];
std::cout << coord[i][j] << std::endl;
}
}
I used another PC with a different OS (i.e. Ubuntu) and it is running fine. Not sure what the problem was. Probably something run with my compiler and/or editor on the first computer.

Problem with ellipse (rotated): incorrect position of any point is detected

When the ellipse is not rotated with this formula 1. If value = 1 - point on the ellipse, if value > 1 - outside, if value < 1 - inside. The program works correctly.
Code:
int checkPointNoAngle(int x0, int y0, int x, int y, int a, int b)
{
int value = (pow((x - x0), 2) / pow(a, 2)) + (pow((y - y0), 2) / pow(b, 2));
return value;
}
I need to work with a rotated ellipse, so I used formula 2.
Now the program incorrectly determines the position of the point.
int checkPoint(int x0, int y0, int x, int y, int a, int b)
{
int angle = 90;
int value = (pow(cos(angle * M_PI / 180)*((x - x0)+sin(angle * M_PI / 180)*(y-y0)), 2) / pow(a, 2)) + (pow(sin(angle * M_PI / 180) * ((x - x0) - cos(angle * M_PI / 180) * (y - y0)), 2) / pow(b, 2));
return value;
}
I drawing an ellipse using this code:
for (int t = 0; t < 360; t++)
{
int x = a * cos(t);
int y = b * sin(t);
int x1 = x * cos(angle * M_PI / 180) + y * sin(angle * M_PI / 180);
int y1 = -x * sin(angle * M_PI / 180) + y * cos(angle * M_PI / 180);
SDL_RenderDrawPoint(ren, x1 + centerX, y1 + centerY);
}
The program draws the ellipse correctly, but determines the position of the point incorrectly.
Examples of work:
3,4,5,6.
Example 4 and 5 works correctly with the checkPointNoAngle method.
I need to rotate the ellipse, so I created checkPoint method.
Example 6 indicates a bug.
The code was confusing a little bit. I tried to simplify the code corresponding to rotation and inverse rotation. The following code seems to work.
#include <iostream>
#include <vector>
#include <cmath>
struct Pt {int x, y;};
double checkPoint(int x0, int y0, int x, int y, int a, int b, int angle) {
double ang = (angle * M_PI)/180;
x = x - x0;
y = y - y0;
double xp = cos(ang)*x + sin(ang)*y;
double yp = -sin(ang)*x + cos(ang)*y;
double value = (xp*xp) / (a*a) + (yp*yp) / (b*b);
return value;
}
std::vector<Pt> gene_ellipse (int centerX, int centerY, int angle, int a, int b) {
std::vector<Pt> v;
double c = cos (angle * M_PI/180);
double s = sin (angle * M_PI/180);
for (int t = 0; t < 360; t++) {
double tt = M_PI * t / 180.0;
double x = a * cos(tt);
double y = b * sin(tt);
int x1 = x * c - y * s;
int y1 = x * s + y * c;
v.push_back (Pt{x1 + centerX, y1 + centerY});
}
return v;
}
int main () {
int centerX = 320;
int centerY = 240;
int angle = 120; // in degrees
int a = 200;
int b = 100;
int index = 25;
auto v = gene_ellipse (centerX, centerY, angle, a, b);
double check = checkPoint (centerX, centerY, v[index].x, v[index].y, a, b, angle);
std::cout << "check = " << check << "\n";
}

C++ Function being Skipped [duplicate]

This question already has answers here:
Calling a function in main
(4 answers)
Closed 4 years ago.
So I'm trying to make a simple pool ball simulation, and when trying to check the collision between balls, my bounce function is being skipped in the loop. There should be a display on the console with the random letters in the function bounce in the PoolTable.cpp file, but its skipped and doesn't process the hits or output the text to the console. Not sure why its not running the function. No warnings. No errors. compiles fine. Im on windows machine, using code blocks, and the GLUT library/project.
Walkthrough
So I initialize and place the balls with the constructor. Then I draw the balls on the screen with the drawBalls function. After drawing the balls, i update their positions and move them with moveBalls function. After moving each ball, while still in the moveball function, I check for collisions with checkCollisions function. checkCollisions then starts two for loops, but never runs the bounce function, as the balls don't bounce off eachother, and the cout isn't printed in the terminal. for some reason it is skipped.
PoolTable.cpp
#include "PoolTable.h"
#include "poolball.h"
#include "Graphics.h"
#include <iostream>
using namespace std;
#include <cmath>
PoolTable::PoolTable( int x){
placeBalls( x );
}
void PoolTable::placeBalls( int x ){
number_of_balls = x;
for( int i = 0; i < x; i++){
balls[i].setX( balls[i].getRadius() + i * 20 );
balls[i].setY( balls[i].getRadius() + i * 30 );
}
}
double find_angle(double vx, double vy) {
// determine the angle between poolballs when they collide
double t; double PI = acos(-1.0);
if(vx < 0) // vertical collision
t = PI + atan(vy/vx);
else if(vx > 0.0 && vy >= 0.0) // 1st quardant collision
t = atan(vy/vx);
else if(vx > 0.0 && vy < 0.0) //
t = 2.0*PI + atan(vy/vx);
else if( vx == 0.0 && vy == 0.0)
t = 0.0;
else if(vx == 0 && vy >= 0.0)
t = PI/2.0;
else
t = 1.5 * PI;
return t;
}
void PoolTable::bounce(int i, int j) {
cout << "klasdjflkadsjflkasjfsadk" << endl;
double PI = acos(-1.0);
double x1 = balls[i].getX();
double y1 = balls[i].getY();
double x2 = balls[j].getX();
double y2 = balls[j].getY();
double dx = x2 - x1;
double dy = y2 - y1;
double dist = sqrt(dx*dx+dy*dy);
// did a collision occur
if(dist <= 2 * balls[i].getRadius()) {
double phi; // angle between the two ball centers
if(dx == 0.0)
phi = PI/2.0;
else
phi = atan2 (dy, dx);
// now compute the total velocities of the two balls
double vx1 = balls[i].xSpeed;
double vy1 = balls[i].getYSpeed();
double v1total = sqrt(vx1*vx1 + vy1*vy1);
double vx2 = balls[j].getXSpeed();
double vy2 = balls[j].getYSpeed();
double v2total = sqrt(vx2*vx2 + vy2*vy2);
// find the angle of each ball's velocity
double ang1 = find_angle(vx1,vy1);
double ang2 = find_angle(vx2,vy2);
// transform velocities into normal.tangential components
double v1xr = v1total * cos(ang1 - phi);
double v1yr = v1total * sin(ang1 - phi);
double v2xr = v2total * cos(ang2 - phi);
double v2yr = v2total * sin(ang2 - phi);
// now find the final velocities (assuming equal mass)
double v1fxr = v2xr;
double v2fxr = v1xr;
double v1fyr = v1yr;
double v2fyr = v2yr;
// reset the velocities
balls[i].setXSpeed(cos(phi)*v1fxr + cos(phi+PI/2)*v1fyr);
balls[i].setYSpeed(sin(phi)*v1fxr + sin(phi+PI/2)*v1fyr);
balls[j].setXSpeed(cos(phi)*v2fxr + cos(phi+PI/2)*v2fyr);
balls[j].setYSpeed(sin(phi)*v2fxr + sin(phi+PI/2)*v2fyr);
}
}
void PoolTable::checkCollisions(void){
for( int i = 0; i < number_of_balls; i++){
for( int j = i + 1; j < number_of_balls; j++){
bounce(i, j);
}
}
}
void PoolTable::moveBalls(void){
for( int i = 0; i < number_of_balls; i++){
balls[i].move();
void checkCollisions();
}
}
void PoolTable::drawBalls(void){
for( int i = 0; i < number_of_balls; i++){
balls[i].draw();
}
}
void checkCollisions(); (in moveBalls) is a function prototype, not a function call. Remove the void.

Perlin Noise 2D: turning static into clouds

I am trying to wrap my head around Perlin noise.
This article has helped and I have been trying to recreate the cloud type images that it provides.
My noise code is as follows:
#include "terrain_generator.hpp"
using namespace std;
#define PI 3.1415927;
float noise(int x, int y)
{
int n = x + y * 57;
n = (n<<13) ^ n;
return (1.0 - ( (n * ((n * n * 15731) + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0);
}
float cosine_interpolate(float a, float b, float x)
{
float ft = x * PI;
float f = (1 - cos(ft)) * 0.5;
float result = a*(1-f) + b*f;
return result;
}
float smooth_noise_2D(float x, float y)
{
float corners = ( noise(x-1, y-1)+noise(x+1, y-1)+noise(x-1, y+1)+noise(x+1, y+1) ) / 16;
float sides = ( noise(x-1, y) +noise(x+1, y) +noise(x, y-1) +noise(x, y+1) ) / 8;
float center = noise(x, y) / 4;
return corners + sides + center;
}
float interpolated_noise(float x, float y)
{
int x_whole = (int) x;
float x_frac = x - x_whole;
int y_whole = (int) y;
float y_frac = y - y_whole;
float v1 = smooth_noise_2D(x_whole, y_whole);
float v2 = smooth_noise_2D(x_whole, y_whole+1);
float v3 = smooth_noise_2D(x_whole+1, y_whole);
float v4 = smooth_noise_2D(x_whole+1, y_whole+1);
float i1 = cosine_interpolate(v1,v3,x_frac);
float i2 = cosine_interpolate(v2,v4,x_frac);
return cosine_interpolate(i1, i2, y_frac);
}
float perlin_noise_2D(float x, float y)
{
int octaves=5;
float persistence=0.5;
float total = 0;
for(int i=0; i<octaves-1; i++)
{
float frequency = pow(2,i);
float amplitude = pow(persistence,i);
total = total + interpolated_noise(x * frequency, y * frequency) * amplitude;
}
return total;
}
To actually implement the algorithm, I am trying to make the clouds he depicted in the article.
I am using openGL and I am making my own texture and pasting it onto a quad that covers the screen. That is irrelevant though. In the code below, just know that the set pixel function works correctly and that its parameters are (x, y, red, green, blue).
This is essentially my draw loop:
for(int y=0; y<texture_height; y++)
{
for(int x=0; x<texture_width; x++)
{
seed2+=1;
float Val=perlin_noise_2D(x,y);
Val = Val/2.0;
Val = (Val + 1.0) / 2.0;
setPixel(x,y,Val,Val,Val);
}
}
What I get is the following:
How can I manipulate my algorithm to achieve the effect I am looking for? changing the persistence or number of octaves doesn't seem to do much at all.
As your result looks almost like white noise, your samples are probably too far apart within the perlin noise. Try using something smaller than the pixel coordinates to evaluate the noise at.
Something similar to this:
perlin_noise_2D((float)x/texture_width,(float)y/texture_height);

My Gravitational Pull Algorithm behaves Oddly in Certain Situations

While trying to create my own physics engine (don't try persuading me not to), I decided to create a class for each pixel, called Particle, this system has an x and a y, and a x and y velocity, as shown below. Unfortunately, the code for calculateGravitationalVelocity doesn't abide by the laws of physics in certain situations. For example, if the x of the particle and the x of the other particle is the same, the particle will fall towards the object realistically, but when the particle gets too close, it pings off towards the positive x. I am only going to include the class source code, but I can include the source code of the other file, though it is partly written in SFML
Particle.cpp:
#include <iostream>
#include <string>
#include <math.h>
class Particle
{
private:
//Coords:
double x, y;
//Velocities:
double xVelocity = 0;
double yVelocity = 0;
//Material:
std::string material = "Generic";
//Mass:
double mass = 0;
public:
//Coords:
void setCoords(double, double);
float getCoords(char);
//Velocities:
void giveVelocity(char, float);
void setVelocity(char, float);
float getVelocity(char);
//Gravitational Velocity:
void calculateGravitationalVelocity(Particle);
//Material:
void setMaterial(std::string);
std::string getMaterial();
//Mass:
void setMass(double);
double getMass();
//Update:
void update();
};
//Coords:
void Particle::setCoords(double newX, double newY)
{
x = newX;
y = newY;
}
float Particle::getCoords(char axis)
{
if (axis == 'x')
{
//return floor(x);
return x;
}
else if (axis == 'y')
{
//return floor(y);
return y;
}
}
//Velocities:
void Particle::giveVelocity(char axis, float addedVelocity)
{
if (axis == 'x') {xVelocity = xVelocity + addedVelocity;}
else if (axis == 'y') {yVelocity = yVelocity + addedVelocity;}
}
void Particle::setVelocity(char axis, float newVelocity)
{
if (axis == 'x') {xVelocity = newVelocity;}
else if (axis == 'y') {yVelocity = newVelocity;}
}
float Particle::getVelocity(char axis)
{
if (axis == 'x') {return xVelocity;}//floor(xVelocity);}
else if (axis == 'y') {return xVelocity;}//floor(yVelocity);}
}
//Gravitational Velocity (Where the problems probably are):
void Particle::calculateGravitationalVelocity(Particle distantParticle)
{
//Physics constants:
const double pi = 3.14159265359; //Pi
const double G = 0.00000000006673; //Gravitational Constant (or Big G)
//Big Triangle Trigonometry:
//Get coords of moving particle:
double x1 = x;
double y1 = y;
//Get coords of particle with gravity:
double x2 = distantParticle.getCoords('x');
double y2 = distantParticle.getCoords('y');
if (x1 != x2)
{
//Work out the angle:
double A = atan((y2 - y1) / (x2 - x1)) * 180 / pi;
//Remove the minus sign:
A = fabs(A);
//Small Triangle Trigonometry:
//Work out the hypotenuse of the big triangle:
double hyp = sqrt(pow(x2 - x1, 2) + pow(y2 - y1, 2));
//Work out the gravitational field (hyp of small triangle):
long double gravitationalField = G * (distantParticle.getMass() / pow(hyp, 2));
//For testing purposes:
//std::cout << "X: " << (cos(A) * gravitationalField) / 1000 << std::endl;
//std::cout << "Y: " << (sin(A) * gravitationalField) / 1000 << std::endl;
//Work out the X velocity:
xVelocity = xVelocity + (cos(A) * gravitationalField) / 1000;
//Work out the Y velocity:
yVelocity = yVelocity + (sin(A) * gravitationalField) / 1000;
}
else
{
//Work out the hypotenuse of the big triangle:
double hyp = sqrt(pow(x2 - x1, 2) + pow(y2 - y1, 2));
//Work out the gravitational field (hyp of small triangle):
long double gravitationalField = G * (distantParticle.getMass() / pow(hyp, 2));
yVelocity = yVelocity + gravitationalField / 1000;
}
}
//Material:
void Particle::setMaterial(std::string newMaterialType)
{
material = newMaterialType;
}
std::string Particle::getMaterial()
{
return material;
}
//Mass:
void Particle::setMass(double newMass)
{
mass = newMass;
}
double Particle::getMass()
{
return mass;
}
//Update:
void Particle::update()
{
x = x + xVelocity;
y = y + yVelocity;
}
I am sorry for the very open question, and it probably goes against the rules somewhere, but I couldn't find it. The code for working out mostly uses a two triangles to make a x and y velocity. Here is an image of what I was hoping the code would do as a triangle (sorry it doesn't look great, but I like using a whiteboard):
You don't need to perform any trigonometric calculation.
...
//Get coords of particle with gravity:
double x2 = distantParticle.getCoords('x');
double y2 = distantParticle.getCoords('y');
// Get difference vector
double rx = x1 - x2;
double ry = y1 - y2;
// square of distance
double r2 = rx * rx + ry * ry;
// distance
double r = sqrt (r2);
if (r != 0) {
// normalize difference vector
double ux = rx / r;
double uy = ry / r;
// acceleration of gravity
double a = - G * distantParticle.getMass() / r2;
xVelocity += a * ux / 1000;
yVelocity += a * uy / 1000;
}
}