View unanswered posts | View active topics It is currently Fri Dec 19, 2014 3:59 am






Reply to topic  [ 15 posts ] 
Lowering motor power? 
Author Message
Rookie

Joined: Wed Jan 21, 2009 4:08 pm
Posts: 10
Post Lowering motor power?
I'm trying to figure out how to run a motor at half power when I press a button. For instance, when I press one of the right trigger buttons on a joystick I want the motor to run at half speed and when I'm not pressing the trigger button I want the motor to run at full speed. I've tried things like "joystick.joy1_y1 / 4" and other similar ideas I thought would work and searched around on the forums, but came up with nothing. Can someone tell me how I would accomplish this? Any help would be appreciated. Thank you. :)


Mon Feb 02, 2009 4:22 pm
Profile
Novice

Joined: Mon Oct 13, 2008 6:29 pm
Posts: 75
Location: Florida, USA
Post Re: Lowering motor power?
try

Code:
 if (joy1Btn(5))
{
  motor[motorA] = 50
}

else
{
  motor[motorA] =100
}

_________________
PHUHS Robotics
Team 516 FTW

Daytona Robofest Winning Alliance Captain
Daytona Robofest Inspire Award


Mon Feb 02, 2009 4:41 pm
Profile
Novice

Joined: Fri Oct 24, 2008 8:58 am
Posts: 87
Post Re: Lowering motor power?
Combine your original idea with 10nisman's

Code:
if (joy1Btn(5))
{
  motor[motorA] = joystick.joy1_y1 / 2;
}
else
{
  motor[motorA] = joystick.joy1_y1;
}



Mon Feb 02, 2009 10:31 pm
Profile
Rookie

Joined: Wed Jan 21, 2009 4:08 pm
Posts: 10
Post Re: Lowering motor power?
chadgeorge wrote:
Combine your original idea with 10nisman's

Code:
if (joy1Btn(5))
{
  motor[motorA] = joystick.joy1_y1 / 2;
}
else
{
  motor[motorA] = joystick.joy1_y1;
}



I tried that but it still doesn't work. I also tried it without the button command. Dividing the joystick command doesn't work for some reason. Any other ideas?


Last edited by Kcmny on Thu Feb 05, 2009 4:57 pm, edited 1 time in total.



Thu Feb 05, 2009 2:12 pm
Profile
Novice

Joined: Mon Oct 13, 2008 6:29 pm
Posts: 75
Location: Florida, USA
Post Re: Lowering motor power?
try this
Code:
if (joy1Btn(5))
{
  motor[motorA] = (joystick.joy1_y1 ) * 100/127 * 0.5;
}
else
{
  motor[motorA] = (joystick.joy1_y1) * 100/127;
}


100/127 is the scale to have "maximum" control over your motors, remember to change motorA to which ever motor is on your drivetrain and create a statement for a second moto,r if you have one ex. motor[motorE] = (joystick.joy1_y2) * 100/127; .

_________________
PHUHS Robotics
Team 516 FTW

Daytona Robofest Winning Alliance Captain
Daytona Robofest Inspire Award


Thu Feb 05, 2009 4:55 pm
Profile
Rookie

Joined: Wed Jan 21, 2009 4:08 pm
Posts: 10
Post Re: Lowering motor power?
Cool, thanks. I've give it a try tomorrow at school.


Thu Feb 05, 2009 5:00 pm
Profile
Rookie

Joined: Wed Jan 21, 2009 4:08 pm
Posts: 10
Post Re: Lowering motor power?
It still doesn't work. Could it be because I have this in my code also?

Code:
if ((joystick.joy1_y1 >= 5) || (joystick.joy1_y1 <= -5))
    {
      motor[motorD] = joystick.joy1_y1;
    }
    else
    {
      motor[motorD] = 0;
    }


Fri Feb 06, 2009 2:07 pm
Profile
Novice

Joined: Mon Oct 13, 2008 6:29 pm
Posts: 75
Location: Florida, USA
Post Re: Lowering motor power?
please post you whole teleop code and im sure everybody will try their best to help.

_________________
PHUHS Robotics
Team 516 FTW

Daytona Robofest Winning Alliance Captain
Daytona Robofest Inspire Award


Fri Feb 06, 2009 5:08 pm
Profile
Novice

Joined: Fri Oct 24, 2008 8:58 am
Posts: 87
Post Re: Lowering motor power?
without seeing the actual code, I would guess "yes" if that code is after the other code it could be the cause of the problem.

You should never set the power of the motor more than once in any loop of your program.
Instead use a temporary variable like this:

Code:

int tempMotorD;


tempMotorD = joystick.joy1_y1;

if (tempMotorD >-5 && tempMotorD <5)
{
  tempMotorD = 0;
}

if (joy1Btn(5))
{
  tempMotorD /= 2;
}

motor[motorD] = tempMotorD;




But I recommend you use the deadband removal code I posted earlier, as it has a smoother result.
http://www.robotc.net/forums/viewtopic.php?f=33&t=1183

If you still have problems then please post the code and we can help you get it working.


Fri Feb 06, 2009 5:52 pm
Profile
Rookie

Joined: Sat Nov 22, 2008 7:14 pm
Posts: 12
Location: NJ
Post Re: Lowering motor power?
Can't you just do this?

Code:
if(joy1Btn(1))
{
motor[motorD] = joystick.joy1_y1/2;
}

else
{
motor[motorD] = joystick.joy1_y1;
}


I have tried this before it works, you may just not know it try.

Try dividing the joystick by like 50. I notice that even at 5% its hard to notice a speed change

Look at the NXT devices screen in RobotC when running, watch the motor percent and tell me if it changes when you press the button and move the joy.

Also about that part in your code, thats fine, I have it, I am guessing its to stop drift on the remote, but you need to put the speed cut function inside the anti-drift function where you put the motor code.

So this:

Code:
if ((joystick.joy1_y1 >= 5) || (joystick.joy1_y1 <= -5))
    {
      if(joy1Btn(1))
      {
        motor[motorD] = joystick.joy1_y1/2;
      }

      else
      {
        motor[motorD] = joystick.joy1_y1;
      }
    }
    else
    {
      motor[motorD] = 0;
    }

_________________
Ethan Spitz
Team 464 Programmer


Fri Feb 06, 2009 7:17 pm
Profile
Novice

Joined: Fri Oct 24, 2008 8:58 am
Posts: 87
Post Re: Lowering motor power?
Ethan is right. The problem is probably not with your code but rather your expectations of how the motors respond.

Most of the speed change of the robot happens in the lower 0-75% of motor power, the upper 75%-100% will have much less effect on the response of the robot.

Also if you think about it, the way you need to control the robot makes this situation even worse since when the robot is going "fast" you really don't need fine control around 80%-100% of the top speed. My experience has been that if a driver wants more than 50% he'll normally ask for 100%.

Now the reason you probably want to reduce power is to get really fine control of the robot when its moving "slow". Also you wanted a deadband where the robot is completely off.

There's a way of doing this that results in very very good control at low speeds and full power when you need it. Also its very intuitive for the driver and no switching is required.

Code:

task main()
{
int axis_map[] = {
       2,    4,    6,    8,   10,   12,   14,   16,   18,   20,
      22,   25,   27,   29,   32,   34,   37,   39,   42,   44,
      47,   50,   52,   55,   58,   61,   64,   67,   70,   73,
      77,   80,   83,   87,   90,   94,   97,  101,  105,  109,
     113,  117,  121,  125,  129,  134,  138,  143,  147,  152,
     157,  162,  167,  172,  177,  183,  188,  194,  200,  205,
     212,  218,  224,  231,  237,  244,  251,  258,  265,  273,
     280,  288,  296,  304,  313,  321,  330,  339,  348,  358,
     368,  378,  388,  398,  409,  420,  432,  443,  455,  468,
     480,  493,  507,  520,  534,  549,  564,  579,  595,  611,
     628,  645,  662,  680,  699,  718,  738,  759,  779,  801,
     823,  846,  870,  894,  920,  946,  972,  1000, 1000};

int remapAxis(int value)
{
    int t=1;

    if (value < 0)
    {
        value *= -1;
        t=-1;
        value += 1;
    }
    if (value < 11)
        return 0;

    value -= 11;
    t *= axis_map[value];
    return t;
}
task main()
{
   while(true)
   {
      getJoystickSettings(joystick);

      motor[LeftDrive] = remapAxis(joystick.joy1_y1) / 10;
      motor[RightDrive] = remapAxis(joystick.joy1_y2) / 10;
   }
}



This code basically uses a lookup table to transform every possible joystick value to the desired % of motor power (its actually outputs 0-1000 so divide by 10 if you're going to use it directly on a motor)

The function the table implements is a log-log function which rises very slowly from 0-75% and much faster from 75-100%.

Also here's the python script that will generate the C code for the table and remapAxis() function if you want to change the deadband , mapping function or final scaling. It also makes a tabbed data file that is easy to import into Excel to graph your function.

Code:
from math import exp

def gcd(a,b):
    """Return greatest common divisor using Euclid's Algorithm."""
    while b:     
        a, b = b, a % b
    return a

def mapAxisDeadband(src, deadband):
    result = [];
    for x in range(src[0], src[1]+1):
        y = x
        if x < 0:
            if x < deadband[0]:
                x -= deadband[0]
            else:
                x = 0
               
            scale =  float(src[0] - deadband[0]);
            result.append( (y, -x / scale) )
           
        elif x >= 0:
            if x > deadband[1]:
                x -= deadband[1]
            else:
                x = 0
               
            scale = float(src[1] - deadband[1]);
            result.append(  (y, x / scale) )
       
    return result

def singleLog(x):
    return exp(x) - 1

def doubleLog(x):
    return exp(exp(x) - 1) - 1

def mapAxisFunc(src, f):
    result = []
   
    scale = f(1)
   
    for k, x in src:
        if x < 0:
            y = - f(-x) / scale
        else:
            y = f(x) / scale

        result.append( (k,y) )
   
    return result

def mapAxisScale(src, scale=100, integer = True):
    result = []
    for k, x in src:
        y = x * scale
        if integer:
            y = int(round(y))
           
        result.append( (k, y) )
    return result
if __name__ == "__main__":
    map = mapAxisDeadband( src = (0,128) ,
                           deadband = (0, 10))

    map = mapAxisFunc(map, doubleLog)
   
    map = mapAxisScale(map, scale=1000)
   
    map.append(map[-1])
   
    f = open("map.cvs", "wt")
   
    for x, y in map:
        f.write( "%s\t%s\n" % (x/128.0,y))
    f.close()
   
   
    zero_start = None;
    zero_end = None;
   
    result = "int axis_map[] = {\n    "
    j = 0
    for i in range(len(map)):
        x, y = map[i]
   
        if zero_end == None and zero_start != None and y != 0:
            zero_end = i
       
        if zero_start == None and y == 0:
            zero_start = i
           
        if y == 0:
            continue
       
        if j > 0 and j % 10 == 0:
            result += ",\n    "
           
        if j % 10 != 0:
            result += ", "
       
        result += "% 4d" % y
        j += 1;
       
    result +=  "};\n"
           
    print zero_start, zero_end;
   
    result += "\nint remapAxis(int value)\n{\n    int t=1;\n\n"
    result += "    if (value < 0)\n    {\n        value *= -1;\n        t=-1;\n        value += 1;\n    }\n"
    result += "    if (value < %s)\n        return 0;\n\n" % zero_end;
   
    result += "    value -= %s;\n" % (zero_end - zero_start);
    result += "    t *= axis_map[value];\n"
    result += "    return t;\n"
    result += "}\n"
   
   
    f = open("axis_map.c", "wt")
    f.write(result)
    f.close()


Hope it helps.


Sat Feb 07, 2009 2:18 pm
Profile
Rookie

Joined: Wed Jan 21, 2009 4:08 pm
Posts: 10
Post Re: Lowering motor power?
Wow, thanks a lot guys. Had no idea I'd get this much response.


Sun Feb 08, 2009 3:59 am
Profile
Rookie

Joined: Wed Jan 21, 2009 4:08 pm
Posts: 10
Post Re: Lowering motor power?
Okay, after returning to school I tried everyone's idea, but none of them worked. I'm currently using Chad's idea from another post to obtain a deadband, so my code looks like this:

Code:
#include "JoystickDriver.c"

int handleAxis(int val, int dbMin, int dbMax)
{

  // 1. Remove the Deadband and shift everything back to zero
   if (val <= dbMin)
      val = (val - dbMin);
   else if (val >= dbMax)
      val = (val - dbMax);
   else
      val = 0;

   // 2. Now realign the axis so that the output is 0-100 between dbMax and +127
   //    and -100 to 0 between -128 and dbMin.

   if (val > 0)
   {
    val *= 100;
    val /=  (127 - dbMax);          // dbMax should be >= 0
   }
   else
   {
    val *= 100;
    val /= (128 + dbMin);             // dbMin should be <= 0
   }


   return val;
}

void handleJoystick()
{
   joystick.joy1_x1 = handleAxis(joystick.joy1_x1, -10, 10);
   joystick.joy1_y1 = handleAxis(joystick.joy1_y1, -10, 10);
   joystick.joy1_x2 = handleAxis(joystick.joy1_x2, -10, 10);
   joystick.joy1_y2 = handleAxis(joystick.joy1_y2, -10, 10);

   joystick.joy2_x1 = handleAxis(joystick.joy2_x1, -10, 10);
   joystick.joy2_y1 = handleAxis(joystick.joy2_y1, -10, 10);
   joystick.joy2_x2 = handleAxis(joystick.joy2_x2, -10, 10);
   joystick.joy2_y2 = handleAxis(joystick.joy2_y2, -10, 10);
}

task main()
{
  getJoystickSettings(joystick);
  handleJoystick();
  motor[motorD] = joystick.joy1_y1;
  motor[motorE] = joystick.joy1_y2;
  motor[motorF] = joystick.joy2_y1;
  motor[motorG] = joystick.joy2_y1;
}


Motor D is the left wheel, motor E is the right wheel, and motor F and G control the arm. I've tried doing "joystick.joy1_y1/2" and tried dividing it by bigger numbers, but the motor runs at 100% each time. I'm starting to think that this problem may be linked to another problem I'm having. My team is also in the process of creating an autonomous program and when we write a motor command, like this: "motor[motorD] = 50" the motor still runs at 100%. Even when we put in a motor power of 1 is still runs at 100. Could this two problems be linked together? Again, any help is greatly appreciated. Thank you.


Tue Feb 10, 2009 11:10 pm
Profile
Rookie

Joined: Thu Jan 08, 2009 7:51 pm
Posts: 25
Post Re: Lowering motor power?
Uhh have you tried turning "PID Control" off?

_________________
It must be user error.


Wed Feb 11, 2009 9:46 am
Profile WWW
Rookie

Joined: Wed Jan 21, 2009 4:08 pm
Posts: 10
Post Re: Lowering motor power?
Hehe, thank you so much, Hobbseltoff. I had no idea what checking that box meant, but I always did it by default. I forgot to check the motor power but my other problem was fixed, so I'm sure the motor power problem will be fixed. Thanks again. :D


Wed Feb 11, 2009 4:31 pm
Profile
Display posts from previous:  Sort by  
Reply to topic   [ 15 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.