I have created an NXT printer before using .pbm files, where the file is read on the nxt and then printed out.
http://en.wikipedia.org/wiki/Netpbm_formatHowever, now I am trying to instead print pixels, print strokes.
I have created a C++ that parses the pbm file into commands for the nxt in the format
D (lower pen)
U (lift pen)
5 9
5 10
5 11 (coordinates)
I did try to do this in RobotC and it did work, but as I increased the resolution, the array became too large to fit in the NXT's flash memory so I resorted to doing it on the pc.
However, the issue now is for the arm to move to a specific coordinate.
Always, I come back to this issue and sometimes it gets better, sometimes, worse.
Here is the code for the function of moving it to a coordinate. It seems fine to me, yet the movements are always innacurate by up to 1cm (note that my gearing for the two joints are 56:1, 120:1).
/* Functions for a SCARA robot
Some of these variables may seem useless (for example a1 and a2) as I have used them in the past but then realised I didn't need them
but may need them in the future.
*/
const int speed = 50; //speed
const float mm = 1; //mm per pixel
const float arm1 = 15.2*7.95*mm, //Length of arm1 in m
arm2 = 14*7.95*mm, //Length of arm2 in mm
arm1R = 56, //Gear ratios
arm2R = -120;
int asign1,asign2;
float s1,s2; //speed of motors
float t; //time to move to coordinate(in some form of measurement that I don't know)
long a1,a2; //the amount still needed to move to the angle
long target1,target2; //targets for the motor to move to
long encoderBBegin = (arm1R*90), //The start numbers of the motor encoders (90 and 180 degrees so the arm forms a straight line)
encoderCBegin = (arm2R*180);
void moveToAngle(float angle1, float angle2){ //function to move the arm to a certain position (using two angles)
target1 = ceil(angle1 * arm1R - encoderBBegin);
a1 = target1;
target2 = ceil(angle2 * arm2R - encoderCBegin);
a2 = target2;
// find t (time in s)
asign1=1;
asign2=1;
if(a1<0){
a1*=-1;
asign1 = -1;
}
if(a2<0){
a2*=-1;
asign2 = -1;
}
if(a1>a2){
t=a1/speed;
}
else{
t=a2/speed;
}
if(t<0){
t *= -1;
}
// find speeds
s1 = ceil(asign1*a1/t);
s2 = ceil(asign2*a2/t);
nxtDisplayTextLine(3,"%f - %d",angle1,target1);
nxtDisplayTextLine(4,"%f - %d",angle2,target2);
if(target1==0 && target2==0){
return;
}
else if(target1==0){
nMotorEncoderTarget[motorC] = target2; // set the target for Motor Encoder of Motor C
motor[motorC] = s2;
while(nMotorRunState[motorC] != runStateIdle){}
motor[motorC] = 0; // motor B is stopped at a power level of 0
}
else if(target2==0){
nMotorEncoderTarget[motorB] = target1; // set the target for Motor Encoder of Motor C
motor[motorB] = s1;
while(nMotorRunState[motorB] != runStateIdle){}
motor[motorB] = 0; // motor B is stopped at a power level of 0
}
else{
nMotorEncoderTarget[motorB] = target1; // set the target for Motor Encoder of Motor B
nMotorEncoderTarget[motorC] = target2; // set the target for Motor Encoder of Motor C
motor[motorB] = s1;
motor[motorC] = s2;
while(nMotorRunState[motorB] != runStateIdle || nMotorRunState[motorC] != runStateIdle){}
motor[motorB] = 0; // motor B is stopped at a power level of 0
motor[motorC] = 0; // motor C is stopped at a power level of 0
}
encoderBBegin = (arm1R*90) + nMotorEncoder[motorB];
encoderCBegin = (arm2R*180) + nMotorEncoder[motorC];
}
void ikinematics(int xx,int yy,float arm1,float arm2){ //function to calculate the angles required
float B = sqrt(pow(xx,2)+pow(yy,2));
float t = atan2(yy,xx);
float theta = (t-acos((pow(arm1,2)+pow(B,2)-pow(arm2,2))/(2*arm1*B)))*180/PI;
float alpha = (acos((pow(arm1,2)-pow(B,2)+pow(arm2,2))/(2*arm1*arm2)))*180/PI;
//move motor B and C to position
alpha=360-alpha;
nxtDisplayTextLine(6,"Target: %d x %d",xx,yy);
moveToAngle(theta,alpha);
}