Chief Delphi

Chief Delphi (http://www.chiefdelphi.com/forums/index.php)
-   Programming (http://www.chiefdelphi.com/forums/forumdisplay.php?f=51)
-   -   Thanks for all your help...and a question (http://www.chiefdelphi.com/forums/showthread.php?t=51341)

brennerator 09-01-2007 02:33

Thanks for all your help...and a question
 
Quick question

I have the 2006 default code loaded up.

If I wanted the trigger (fire) button on the 1 joystick controlling the robot movement to reduce the robots speed to 50% how would I do that.

I tried:

if (p1_sw_trig == 0)
{
pwm13 = pwm14 = Limit_Mix(2000 + p1_y + p1_x - 127);
pwm15 = pwm16 = Limit_Mix(2000 + p1_y - p1_x + 127);
}
else
{
pwm13 = (pwm13-127)*0.5+127;
pwm14 = (pwm14-127)*0.5+127;
pwm15 = (pwm15-127)*0.5+127;
pwm16 = (pwm16-127)*0.5+127;
}


but when the trigger was pressed nothing moved on teh robot!

Any help?

Tottanka 09-01-2007 03:21

Re: Thanks for all your help...and a question
 
i dont know what u ment to do...
Dom you want the robot to move at 50% of its speed when u press the trigger and thats it? or do u also move the joystics Y farward?

brennerator 09-01-2007 03:24

Re: Thanks for all your help...and a question
 
Basically; I want the joysticks to be waay less sensitive when i press the button. I basically want the speed to be halved at every point when the joystick moves.

Tottanka 09-01-2007 03:27

Re: Thanks for all your help...and a question
 
oh i get it...
i havent toucked programming for a year but i can tell you what i'd do:
if (p1_sw_trig == 0) && (p1_y==1)
{

pwm13=pwm14=pwm15=pwm16=(127+0.5*127);
}
else if (p1_sw_trig == 0) && (p1_y==-1)
{

pwm13=pwm14=pwm15=pwm16=(127-0.5*127);
}

bear24rw 09-01-2007 08:16

Re: Thanks for all your help...and a question
 
Quote:

Originally Posted by Tottanka (Post 551942)
oh i get it...
i havent toucked programming for a year but i can tell you what i'd do:
if (p1_sw_trig == 0) && (p1_y==1)
{

pwm13=pwm14=pwm15=pwm16=(127+0.5*127);
}
else if (p1_sw_trig == 0) && (p1_y==-1)
{

pwm13=pwm14=pwm15=pwm16=(127-0.5*127);
}

When would p1_y ever be -1?

Alan Anderson 09-01-2007 09:29

Re: Thanks for all your help...and a question
 
Your code never reads the joysticks if the button is pressed, so it repeatedly divides the pwm values by two until it decays to zero. That's why the robot stops moving.

Try moving the part that reads the joysticks outside the test for the button.
Code:

  pwm13 = pwm14 = Limit_Mix(2000 + p1_y + p1_x - 127);
  pwm15 = pwm16 = Limit_Mix(2000 + p1_y - p1_x + 127);

  if (p1_sw_trig == 1)
  {
    pwm13 = (pwm13-127)/2+127;
    pwm14 = (pwm14-127)/2+127;
    pwm15 = (pwm15-127)/2+127;
    pwm16 = (pwm16-127)/2+127;
  }

It's safe to do it this way because the pwm values don't actually take effect until the Generate_PWMs() call at the end of Process_Data_From_Local_IO().

By the way, if you plan to use timers and serial communication and encoders and other interrupt-based stuff, avoiding pwms 13-16 would be a good idea. They're generated by the user processor and can get somewhat twitchy when interrupts are happening often. Put your motor controls on pwms 1-12 if you want to keep things easy.

(Note that I replaced the multiply by 0.5 with a divide by 2. Keeping everything as integers makes sure that the compiler doesn't try to do floating point calculations, which take up a lot more time and program space.)

Kevin Sevcik 09-01-2007 10:00

Re: Thanks for all your help...and a question
 
Question to Alan (or anyone),

I'm under the impression a >>1 instead of a /2 would work there and would (possibly?) be faster. We've tried this in some spots in code before, however, and I think it corrupts signed variables. Do you (or anyone) have any specific knowledge about the >> operator on this PIC? I was sort of hoping that it or some other operator will do a signed >> operation and carry the signed bit.

brennerator 09-01-2007 12:42

Re: Thanks for all your help...and a question
 
Thanks a lot guys; Ill try this out today!

Eclipse 09-01-2007 15:46

Re: Thanks for all your help...and a question
 
Quote:

Originally Posted by Alan Anderson (Post 552013)
(Note that I replaced the multiply by 0.5 with a divide by 2. Keeping everything as integers makes sure that the compiler doesn't try to do floating point calculations, which take up a lot more time and program space.)

Something else to keep in mind when dealing with data types is that, from experience, the default printf function seems to not like to deal with floating point numbers. I have no idea if it can be modified to change that or if anyone's done that already.....

darist 10-01-2007 22:08

Re: Thanks for all your help...and a question
 
Quote:

Originally Posted by Kevin Sevcik (Post 552033)
Question to Alan (or anyone),

I'm under the impression a >>1 instead of a /2 would work there and would (possibly?) be faster. We've tried this in some spots in code before, however, and I think it corrupts signed variables. Do you (or anyone) have any specific knowledge about the >> operator on this PIC? I was sort of hoping that it or some other operator will do a signed >> operation and carry the signed bit.

The ">>" in C is the "shift right bitwise" operation. Because of the fact that microprocessors use the binary number system (0s and 1s) a "shift right" results in the same thing as "divide by 2 (but throw away the remainder)."

I was looking throug the MCC18 (Microchip's C compiler) User Guide and found this in Appendix B.4:

Quote:

ANSI C Standard: “The result of a right shift of a negative-valued signed integral type (6.3.7).”
Implementation: The value is shifted as if it were an unsigned integral type of the same size (i.e., the sign bit is not propagated).
Sounds to me like the MCC18 compiler does not have a way to make ">>" operate on signed integers.

Good luck!

tseres 07-06-2007 12:14

Re: Thanks for all your help...and a question
 
make a function for it

[from regular code]

if(p1_sw_trig){
dim_down(pwm01);
}

unsigned char dim_down(int input,float factor){
input-=127;
input*=factor //the factor to dim down the output
return input;
}

Salik Syed 08-06-2007 19:12

Re: Thanks for all your help...and a question
 
It won't work on signed integers, because in order to have fast add and subtract between positive integers most procecssors use a twos complement system.
Basically there is a sign bit, and if the bit is enabled then you reverse the 1 for a 0, so if a number is negative it is instead represented by it's not'd equivalent

So -2 would be
11111110 (for an 8 bit signed char)
The most significant bit is the sign bit.

Now lets try adding -2 to 3:
00000011
11111110
---------
00000001

Tada ..
The extra bit overflows and is discarded... so we can use the same logic adding positive and negative numbers together ... yay!


When you try to bit shift a signed int this is what may happen:
11111100 (-3)
becomes 01111110 (126)

You can still bit shift but the sign bit needs to be replaced... you can do this by XORing the result with 10000000



I actually don't think dividing by two using the bit shift operator really matters, most optimizing compilers should realize that an unsigned int is being divided by two and just swap that in at the assembly level. Secondly most first applications I have seen don't even come close to being computationally intensive enough to warrant such an optimization.
(I don't know if this is actually what happens when using MC18 or whatever it's called)

BTW: for printf I think you can just use %f to print floats

Quzarx 13-06-2007 03:43

Re: Thanks for all your help...and a question
 
Quote:

if (p1_sw_trig == 0)
{
pwm13 = pwm14 = Limit_Mix(2000 + p1_y + p1_x - 127);
pwm15 = pwm16 = Limit_Mix(2000 + p1_y - p1_x + 127);
}
else
{
pwm13 = (pwm13-127)*0.5+127;
pwm14 = (pwm14-127)*0.5+127;
pwm15 = (pwm15-127)*0.5+127;
pwm16 = (pwm16-127)*0.5+127;
}
The way this is set up, you are only getting data from the joysticks when the trigger is not on. You always want to get that data, so first, take
pwm13 = pwm14 = Limit_Mix(2000 + p1_y + p1_x - 127);
pwm15 = pwm16 = Limit_Mix(2000 + p1_y - p1_x + 127);
out of the if block, so that you get new data from the joysticks every loop.
Then, if the trigger is on, you want to divide by 2, not multiply by a decimal

Code:

pwm13 = pwm14 = Limit_Mix(2000 + p1_y + p1_x - 127);
pwm15 = pwm16 = Limit_Mix(2000 + p1_y - p1_x + 127);
if (p1_sw_trig == 1)
{
pwm13 = (pwm13-127)/2+127;
pwm14 = (pwm14-127)/2+127;
pwm15 = (pwm15-127)/2+127;
pwm16 = (pwm16-127)/2+127;
}

Because you are getting the data every loop, and the pwm values aren't set until the end of the loop, you can modify them all you want before that point. Previously, you when the trigger was enabled, you were taking the pwm value, which defaults to 127, subtracting 127, making it 0, multiplying that by .5, making it 0 again, and adding 127, making it neutral on the motors.

Another way to do this would be:

Code:

if (p1_sw_trig == 0)
{
pwm13 = pwm14 = Limit_Mix(2000 + p1_y + p1_x - 127);
pwm15 = pwm16 = Limit_Mix(2000 + p1_y - p1_x + 127);
}
else
{
pwm13 = pwm14 = (Limit_Mix(2000 + p1_y + p1_x - 127)-127)/2+127;
pwm15 = pwm 16 (Limit_Mix(2000 + p1_y - p1_x + 127)-127)/2+127;
}

In this case, you are getting the data from the joysticks in both if and else.

seanl 13-06-2007 10:03

Re: Thanks for all your help...and a question
 
if(p1_sw_trig == 1)
{
pwm13=pwm14=(p1_y/2);
pwm15=pwm16=(p2_y/2);
}
else
{
pwm13=pwm14=(p1_y);
pwm15=pwm16=(p2_y);
}

isnt it as simple as that.

fimmel 13-06-2007 13:49

Re: Thanks for all your help...and a question
 
Quote:

Originally Posted by seanl (Post 631640)
if(p1_sw_trig == 1)
{
pwm13=pwm14=(p1_y/2);
pwm15=pwm16=(p2_y/2);
}
else
{
pwm13=pwm14=(p1_y);
pwm15=pwm16=(p2_y);
}

isnt it as simple as that.

that would work for "tank style" drive, i think he meant using a single stick drive.

seanl 13-06-2007 15:47

Re: Thanks for all your help...and a question
 
Quote:

Originally Posted by fimmel (Post 631652)
that would work for "tank style" drive, i think he meant using a single stick drive.

oh.. i dont really have experience with single. personally i prefer tank.
although reducing speed with a button is a nice idea. i might try that out.

fimmel 13-06-2007 18:01

Re: Thanks for all your help...and a question
 
just make sure to test the code with the robot up on blocks or something. just to make sure it wont do any damage
...forest

Quzarx 13-06-2007 20:39

Re: Thanks for all your help...and a question
 
Another way to do it would be to make a few lookup tables. We set up custom curves, so we had a large area that was slow for fine adjustments, and an area of full speed. This also makes so no calculations are needed on the fly, you just load them into the ram.

You would toss something like this (what we used) under the #include's in user_routines.c
Code:

rom unsigned short int Joystick_Array[] = {0,4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,61,62,63,63,64,65,66,67,68,69,69,70,71,72,73,74,75,75,
76,77,78,79,80,81,81,82,83,84,85,86,87,87,88,89,90,90,91,91,92,92,93,93,94,94,94,95,95,96,96,97,97,98,98,99,99,99,100,100,101,101,102,102,103,
103,103,104,104,105,105,106,106,107,107,107,108,108,109,109,110,110,111,111,111,112,112,113,113,114,114,115,115,116,116,116,117,117,118,
118,119,119,120,120,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,135,135,136,136,136,136,137,137,137,138,
138,138,139,139,139,139,140,140,140,141,141,141,141,142,142,142,143,143,143,144,144,144,144,145,145,145,146,146,146,146,147,147,147,148,
148,148,149,149,149,149,150,150,150,151,151,151,151,152,152,152,153,153,153,154,154,154,154,155,155,156,157,158,158,159,160,161,162,163,
164,164,165,166,167,168,169,170,170,171,172,173,174,175,176,176,177,178,179,180,181,182,182,183,184,185,190,194,199,204,208,213,218,222,
227,232,236,241,246,250,255,};

Then to call it:
Code:

Left_Drive = Joystick_Array[p1_y];
Right_Drive = Joystick_Array[p3_y];

(Again, here we use tank style, and used p1 and p3 due to custom control systems (p2 and p4 have all of the button outputs)

That makes so the variable "Left_Drive" and "Right_Drive" are modified pwm values, but not assigned to the pwm yet.

To go with one joystick:
Code:

if (p1_sw_trig == 0)
{
pwm13 = pwm14 = Limit_Mix(2000 + p1_y + p1_x - 127);
pwm15 = pwm16 = Limit_Mix(2000 + p1_y - p1_x + 127);
}
else
{
pwm13 = pwm14 = Limit_Mix(2000 + Joystick_Array[p1_y] + Joystick_Array[p1_x] - 127);
pwm15 = pwm16 = Limit_Mix(2000 + Joystick_Array[p1_y] - Joystick_Array[p1_x + 127);
}

In this case, you would make an array with new values (halves if you want). the joystick gives a value of 0 to 255, so it looks in spot 0, if full reverse in the array, and in this example, would grab a value of 0. 127 points to the 127th. Remember, the first one is spot 0, not 1 in the array. Doing it this way allows you to have multiple curves for drivers, or just change the values completely so you have a larger slow area so you do not need to cut it in half at all.

lukevanoort 13-06-2007 21:31

Re: Thanks for all your help...and a question
 
(This is in regard to the post above mine, which I will not quote, for space considerations)

We do essentially the same thing, the only differences are, we use a slightly different equation, and our lookup table uses unsigned chars instead of short ints (although, in theory both should work, unsigned chars just take up less space). However, instead of just using ours for only our drive system, ours is used for every single joystick controlled movement on our robot. We have found that this greatly increases usability and driveability of our robot and its mechaisms by allowing fine control when necessary (like positioning the wrist for a ringer) and fast control when you need the speed (like driving across the field to a ringer). I would highly recommend at least trying exponential lookup tables, you may be amazed by the improvement such a small change can make.


All times are GMT -5. The time now is 23:34.

Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Copyright © Chief Delphi