View unanswered posts | View active topics It is currently Wed Jul 23, 2014 10:39 am






Reply to topic  [ 7 posts ] 
motor spinning erratically 
Author Message
Rookie
User avatar

Joined: Wed Mar 03, 2010 11:23 pm
Posts: 4
Post motor spinning erratically
Code:
#pragma config(Hubs,  S1, HTMotor,  HTMotor,  none,     none)
#pragma config(Motor,  motorA,          claw,          tmotorNormal, openLoop)
#pragma config(Motor,  mtr_S1_C1_1,     leftDrive,     tmotorNormal, openLoop)
#pragma config(Motor,  mtr_S1_C1_2,     rightDrive,    tmotorNormal, openLoop, reversed)
#pragma config(Motor,  mtr_S1_C2_1,     arm,           tmotorNormal, openLoop, reversed)
#pragma config(Motor,  mtr_S1_C2_2,     bucket,        tmotorNormal, openLoop)
//*!!Code automatically generated by 'ROBOTC' configuration wizard               !!*//

#include "JoystickDriver.c"  //Include file to "handle" the Bluetooth messages.

void startup(){
  motor[leftDrive]=0;
  motor[rightDrive]=0;
  return;
}

float absval(float vara){
  float varb = vara*((vara>0) + ((vara<0)*-1));
  return varb;
}

task main(){
  startup();

  /*VARIABLES*/
  short dzone = 10; //universal controller deadzone (0-128)
  float turnscale = 0.0; //scalar used for turning

  /////////////DEFAULT CRAP////////////////////////
  waitForStart(); //waits for start of teleop phase
  while(true){
    getJoystickSettings(joystick);
    // has the FMS stopped the program
    if (joystick.StopPgm)
    {
      //nxtDisplayTextLine(2, "Disabled"); //re-add this for final
      wait1Msec(50);

      continue;   // go back into top of while loop
    }
    //nxtDisplayTextLine(2, "Enabled"); //re-add this for final
    ///////////END DEFAULT CRAP////////////////////
    /* put the rest of your code here */

    /*NEW DRIVE CODE*/
    //get scale value
        /*this takes the value of the x axis of the right thumbstick of controller 1,
        divides by the max value (128) to get a "unit joystick" reading,
        takes the absolute value of the number to turn it into a directionless scalar,
        and finally, subtracts the value from 1 so the value decreases as the x value gets bigger.
        we end up with a decimal scalar between 0 and 1

        We dont care about deadzones here because we do a deadzone check later on anyway.*/
    turnscale = 1-(absval(joystick.joy1_x2)/128);
    //nxtDisplayString(2,"%1.3f,%1.3f",turnscale,((joystick.joy1_y1/1.28)*turnscale)); //for testing only. remove for final.
    //make motors move
    if((-dzone>joystick.joy1_y1)||(joystick.joy1_y1>dzone)){
          /*none of these will ever be true at the same time as another
          so this is effectivly a case statement made from ifs

          this block checks the status of the x axis of the right thumbstick on controller 1*/
      //right
      if(joystick.joy1_x2>dzone){
        motor[leftDrive]=(joystick.joy1_y1/1.27);
        motor[rightDrive]=(joystick.joy1_y1/1.27)*turnscale;
      }
      //left
      if(-dzone>joystick.joy1_x2){
        motor[leftDrive]=(joystick.joy1_y1/1.27)*turnscale;
        motor[rightDrive]=(joystick.joy1_y1/1.27);
      }
      //straight, within deadzone
      if((-dzone<joystick.joy1_x2)||(joystick.joy1_x2<dzone)){
        motor[leftDrive]=(joystick.joy1_y1/1.27);
        motor[rightDrive]=(joystick.joy1_y1/1.27);
      }
    }
    else{
      motor[leftDrive]=0;
      motor[rightDrive]=0;
    }


    //CLAW CODE
    if(joy1Btn(2)){
      motor[claw]=50;
    }
    else if(joy1Btn(1)){
      motor[claw]=-50;
    }
    else {
      motor[claw]=0;
    }
   
    /*ARM AND BUCKET CODE*/
    //arm
    if((-10>joystick.joy2_y1)||(joystick.joy2_y1>10)){
      motor[arm]=(joystick.joy2_y1/1.27);
    }
    else motor[arm]=0;
   
    //bucket
    if(joy2Btn(5)){
      motor[bucket]=-15;
    }
    else if(joy2Btn(6)){
      motor[bucket]=15;
    }
    else{
      motor[bucket]=0;
    }
   
  }
}


the NEW DRIVE CODE section of the code is, as the name implies, new drive code that i wrote today to replace the old tank drive we had before. basically what it does is pass the value of joy1_y1 to both drive motors, and scales the power to either the left or right motor (depending on direction of joy1_x2) based on how far joy1_x2 is tilted. the issue is that the motor slows down and speeds up rapidly, making the turning system nearly useless.

this was my code before i started today:
Code:
#pragma config(Hubs,  S1, HTMotor,  HTMotor,  none,     none)
#pragma config(Motor,  motorA,          claw,          tmotorNormal, openLoop)
#pragma config(Motor,  mtr_S1_C1_1,     leftDrive,     tmotorNormal, openLoop)
#pragma config(Motor,  mtr_S1_C1_2,     rightDrive,    tmotorNormal, openLoop, reversed)
//*!!Code automatically generated by 'ROBOTC' configuration wizard               !!*//

#include "JoystickDriver.c"  //Include file to "handle" the Bluetooth messages.

void startup(){
  motor[leftDrive]=0;
  motor[rightDrive]=0;
  return;
}

task main(){
  startup();

  /*VARIABLES*/
  short dzone = 10; //universal controller deadzone (0-128)
  short turnscale = 0; //scalar used for turning

  /////////////DEFAULT CRAP////////////////////////
  waitForStart(); //waits for start of teleop phase
  while(true){
    getJoystickSettings(joystick);
    // has the FMS stopped the program
    if (joystick.StopPgm)
    {
      //nxtDisplayTextLine(2, "Disabled"); //re-add this for final
      wait1Msec(50);

      continue;   // go back into top of while loop
    }
    //nxtDisplayTextLine(2, "Enabled"); //re-add this for final
    ///////////END DEFAULT CRAP////////////////////
    /* put the rest of your code here */

    /*NEW DRIVE CODE*/
    //get scale value
        /*this takes the value of the x axis of the right thumbstick of controller 1,
        divides by the max value (128) to get a "unit joystick" reading,
        takes the absolute value of the number to turn it into a directionless scalar,
        and finally, subtracts the value from 1 so the value decreases as the x value gets bigger.
        we end up with a decimal scalar between 0 and 1

        We dont care about deadzones here because we do a deadzone check later on anyway.*/
    turnscale = 1-(abs(joystick.joy1_x2)/128);
    //nxtDisplayString(2,"%1.3f,%1.3f",turnscale,((joystick.joy1_y1/1.28)*turnscale)); //for testing only. remove for final.
    //make motors move
    if((-dzone>joystick.joy1_y1)||(joystick.joy1_y1>dzone)){
          /*none of these will ever be true at the same time as another
          so this is effectivly a case statement made from ifs

          this block checks the status of the x axis of the right thumbstick on controller 1*/
      //right
      if(joystick.joy1_x2>dzone){
        motor[leftDrive]=(joystick.joy1_y1/1.27);
        motor[rightDrive]=(joystick.joy1_y1/1.27)*turnscale;
      }
      //left
      if(-dzone>joystick.joy1_x2){
        motor[leftDrive]=(joystick.joy1_y1/1.27)*turnscale;
        motor[rightDrive]=(joystick.joy1_y1/1.27);
      }
      //straight, within deadzone
      if((-dzone<joystick.joy1_x2)||(joystick.joy1_x2<dzone)){
        motor[leftDrive]=(joystick.joy1_y1/1.27);
        motor[rightDrive]=(joystick.joy1_y1/1.27);
      }
    }
    else{
      motor[leftDrive]=0;
      motor[rightDrive]=0;
    }


    //CLAW CODE
    if(joy1Btn(2)){
      motor[claw]=50;
    }
    else if(joy1Btn(1)){
      motor[claw]=-50;
    }
    else {
      motor[claw]=0;
    }
   
  }
}


i found out that shorts only store integers, and my scalar is a value between 0 and 1, so that was an issue. i switched turnscale to a float, and in the declaration statement changed the 0 to 0.000 so it would store 3 decimal places. its commented out in the code i posted, but i was having the nxt display the scale value. it was still displaying 0 or 1 (integer values), so i figured the only thing that could be wrong is the built in abs function. so i made my own absolute value function that i know supports decimal places. after i implemented that, the scale value was working perfectly, but the motors also started jerking around while they were spinning if i applied the turnscale variable to them.

im thinking the issue is something isnt updating in time for each cycle the code runs through. it might just be a hardware issue though. i dont know. basically what i want to know is, was i right about the absolute value function not supporting decimal places, and is this a hardware issue or a code issue?

i feel like this is a really incoherent post and that i left out a whole ton of information, so if you need to know anything else or need something cleared up, please let me know. :wink:

_________________
FTC team #3032
Team Sigma
Programmer


Wed Dec 29, 2010 10:55 pm
Profile
Expert

Joined: Mon Oct 27, 2008 9:59 pm
Posts: 137
Post Re: motor spinning erratically
Looks like a standard precision error.
Code:
turnscale = 1-(abs(joystick.joy1_x2)/128);

Remember that ROBOTC will evaluate the inner most portion of the statement first following normal order of operations, in this case: "joystick.joy1_x2/128". Since both of these are integers, you're only going to get a 0 (most likely) or a 1 (if the joystick value is 128). The abs function works correctly... you're just passing it bad data, so it is giving you the correct absolute value of that bad data. :)
Try dividing the joystick value by 128.0 and casting the result to a float if needed.
Let us know if you still have any issues.


Mon Jan 03, 2011 11:33 am
Profile
Rookie
User avatar

Joined: Wed Mar 03, 2010 11:23 pm
Posts: 4
Post Re: motor spinning erratically
i used a line to print the turnscale value to the nxt's screen, and it seemed to be a smooth scalar between 0 and 1. all decimal values seemed to work fine. also, in reference to the abs function, i just added (float) to the front of it to typecast it. that seems to have worked just fine. tank drive works correctly, and we ran many tests on the motors. there is no hardware problem there.

my cousin hooked the motor up to an oscilloscope, and the patterns the oscilloscope show reflect the power being sent to the motor. this happens for both motors.

since the nxt is displaying turnscale correctly, and the motors work correctly, im thinking the problem is that im either missing something subtle like a data type, or robot c is having trouble updating all of the values in one cycle. i dont think its the second one though. im using nxtDisplayString(2,"%1.3f,%1.3f",turnscale,((joystick.joy1_y1/1.28)*turnscale)) to see the values, and both values are reading out to be exactly what i want.

just to be clear, the scalar DOES cut the power to one motor or the other, but it does so rapidly jumping from full power to the lower percentage value from turnscale. the jerking is too erratic to be able to tell if the motor is being scaled by the correct value, or just having power cut to it. ill see what i can do about getting videos of the problem and the oscilloscope readout.

E: i put parentheses around the joystick value only. see turnscale = 1-((float)abs(joystick.joy1_x2)/128);. shouldnt that take the absolute value of the joystick value first, and THEN divide by 128? also, the float in green there is what i added after my first post, just to clarify.

_________________
FTC team #3032
Team Sigma
Programmer


Wed Jan 05, 2011 8:41 pm
Profile
Rookie

Joined: Sat Dec 12, 2009 1:10 pm
Posts: 14
Post Re: motor spinning erratically
Your problem is that the motor is being assigned to full power every sycle even if the y value is outside of the deadzone.

Code:
     if((-dzone>joystick.joy1_y1)||(joystick.joy1_y1>dzone)){
          /*none of these will ever be true at the same time as another
          so this is effectivly a case statement made from ifs

          this block checks the status of the x axis of the right thumbstick on controller 1*/
        //right
        if(joystick.joy1_x2>dzone){
          motor[leftDrive]=(joystick.joy1_y1/1.27);
          motor[rightDrive]=(joystick.joy1_y1/1.27)*turnscale;
        }
        //left
        if(-dzone>joystick.joy1_x2){
          motor[leftDrive]=(joystick.joy1_y1/1.27)*turnscale;
          motor[rightDrive]=(joystick.joy1_y1/1.27);
        }
        //straight, within deadzone
        if((-dzone<joystick.joy1_x2)||(joystick.joy1_x2<dzone)){
          motor[leftDrive]=(joystick.joy1_y1/1.27);
          motor[rightDrive]=(joystick.joy1_y1/1.27);
        }
      }


The last if statement is executed every time the first if statement is. I'm having a hard time explaining this so how about I just give you some code that should work (i haven't tested this code but have seen this problem before and this has fixed it.)
Code:
     if((-dzone>joystick.joy1_y1)||(joystick.joy1_y1>dzone)){
          /*none of these will ever be true at the same time as another
          so this is effectivly a case statement made from ifs

          this block checks the status of the x axis of the right thumbstick on controller 1*/
        //right
        if(joystick.joy1_x2>dzone){
          motor[leftDrive]=(joystick.joy1_y1/1.27);
          motor[rightDrive]=(joystick.joy1_y1/1.27)*turnscale;
        }
        //left
        else if(-dzone>joystick.joy1_x2){
          motor[leftDrive]=(joystick.joy1_y1/1.27)*turnscale;
          motor[rightDrive]=(joystick.joy1_y1/1.27);
        }
        //straight, within deadzone
        else{
          motor[leftDrive]=(joystick.joy1_y1/1.27);
          motor[rightDrive]=(joystick.joy1_y1/1.27);
        }
      }


Hopefully that makes it more clear as to what I was saying.

_________________
2 Much Sense


Mon Feb 14, 2011 3:39 pm
Profile WWW
Rookie

Joined: Sun Dec 05, 2010 11:58 am
Posts: 28
Post Re: motor spinning erratically
That code ought to work.
I'm just curious- why are you using both joysticks to drive?


Fri Feb 25, 2011 2:05 pm
Profile
Rookie

Joined: Sat Dec 12, 2009 1:10 pm
Posts: 14
Post Re: motor spinning erratically
I cant speak for Donut or anyone else but for our team "tank drive" (using both joysticks) is easier for our driver to understand and get the robot to do what he wants it to do.

_________________
2 Much Sense


Fri Feb 25, 2011 3:36 pm
Profile WWW
Rookie

Joined: Sun Dec 05, 2010 11:58 am
Posts: 28
Post Re: motor spinning erratically
Oh, that makes sense.
We had a debate in our team about that too.

Either way works fine-you just need to get used to whichever method you use.


Wed Mar 02, 2011 9:30 pm
Profile
Display posts from previous:  Sort by  
Reply to topic   [ 7 posts ] 

Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  



Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software for PTF.