how does it move forward

Woah, this is a smart design! It’s small, and the structure doesn’t look flimsy. How does it run?

Can you upload a video? I would like to show my friends the kiwi drive in action

Magic. Hahaha, I’m kidding; actually there are three “omni-wheels” that are located at 120 degrees from each other, and due to the angle of the wheels, when two are driven the third acts as a caster. It’s all got to do with the vectors of the machine, and since I do not know the formulas off the top of my head, I cannot explain it in full detail. If you want, search “kiwi drive” or "holonomic drive’ on delphi here.

colin,

does this mean you are going to enter the vex comp at the Ra Cha Cha this year?

Greg

it works like a champ with some code from Tom Bottiglieri it should be allot easier to control as for computation I will problem not but team 340 is working on starting a 9th grade team

thank you tom Bottiglieri and Greg Perkins for advise

With Tom’s permission, could you possibly post the section of code that makes the magic work? PLEASE!!!

Well credit needs to be given where it’s deserved. I got the equations for my kiwi code from the living genious, Joel Johnson.

Anyway, here’s what you need to do to make it work:

```
//Make sure variables are unsigned ints... rollovers WILL occur with signed ints
unsigned int trans_x, trans_y, rot;
//Grab inputs (x,y coords in rectangular coordinates and rotation rate)
trans_x = 254 - PWM_in1;
trans_y = 254 - PWM_in2;
rot = 254 - PWM_in4;
//Limit vector length to 127
trans_x = (unsigned int)(37+(254*trans_x)/359);
trans_y = (unsigned int)(37+(254*trans_y)/359);
//Assign and limit wheel outputs
wheel_1 = (unsigned char)limit( (((2*trans_x) + rot) / 3), 0, 254);
wheel_2 = (unsigned char)limit( ((601 + rot - trans_x - (168*trans_y/97)) / 3), 0, 254);
wheel_3 = (unsigned char)limit( ((161 + rot - trans_x + (168*trans_y/97)) / 3) , 0, 254);
```

This assumes you have a limit function, which limits an input value to upper and lower bounds.

```
signed int limit(signed int value, signed int min, signed int max)
{
if (value < min)
{
value = min;
} else if (value > max)
{
value = max;
}
return value;
}
```

That should be all you need, and it **should** work. (It took me about 2 hours to figure out the variables needed to be unsigned. :mad: )

Now I know why I like Tom (oh yeah, and Joe too ) so much!!

The problem is, now I have to go buy some omni wheels for this weekends project

BTW. Do you know how the constant values were determined (ie. 37, 359, 601, 168, 97, 161)? Also, I see you are using PWM_in4 for the rotation value. I assume this is off the left stick X-axis. Knowing these can help me modify this stuff for future projects.

Thanks again!!!

I like that design! It’s so compact and sturdy, good job!

yes this is so much better then my old frame it’s very stiff and compact

I just got this working this morning. I tried for hours last night to code it with EasyC. Apparently doing the math wasn’t so easy with EasyC. :o I’ll figure it out later today. What you see it the video is coded with MPLAB in about 20 minutes.

Very nice design!

There seem to be many variations of Vex holomic robots out there, probably because they are so fun to drive. Here’s the beginnings of my first Vex bot, thanks to the RS sale:

Here’s the underside:

My goal was to design a robot as clean and symmetrical as I could. It took one Starter kit and an additional hardware kit. The orange spacers in the motor mount bracket are the only non-vex parts, from an Erector set. They are conveniently in-between sizes of the vex plastic spacers.

To avoid having to support the axles on the outer sides of the wheels, I set back the motor with these spacers to allow a collar to hold in and support the axle on the motor side inside the bracket.

I’ve added sensors and have devised a scheme (still in the process of Implementation ) to have the robot detect walls and “bounce” off them before hitting with an angle of reflection equal to that of the angle of incidence. I’d like to put it inside a boxed-in area and have it bounce around like an billiard ball for robotics demos.

Thanks.

I really like how clean your assembly looks!

On sensors… from my experience with the the Vex Ultrasonics.

They do a good job of sensing objects directly in front as long as object has a surface that is perpendicular to the sensor. In other words, when approaching a wall at an angle, the sensor wont pick it up very well at all.

Additionally, if you do put your bot in a box, the walls will bounce the 40KHz signal pulses quite a bit, causing misreadings from the controller.

Here’s a thought. Try using the light sensors from the Line Following kit. With a little experimentation, you should be able to fine tune an algorithm to detect the relative distance from the wall based on the amount of light being reflected off of it. The biggest problem you will face with that is consistent light levels, and that may render this option useless. (Remember the difficulties with the CMU cam. and reflected light in 2005?)

Here’s the “documentation.” Its in the PBASIC file that I used to program the KIWI drive 229 did a year or so ago.

```
'KIWI Code Overview
'------------------
'
'Vx, Vy, and w are on the interval -127, 127], but the inputs p2_x, p2_y, p1_x are on the interval [0, 254],
'so we compensate by setting Vx, Vy, and w to the shifted version of the input:
'
' trans_x = p2_x
' trans_y = p2_y
' rot = p1_x
'
' Vx = trans_x - 127
' Vy = trans_y - 127
' w = rot - 127
'
'The kiwi system is characterized by the equation:
'
' Vx ] 1 -1/2 -1/2 ] V1 ]
' Vy ] = 0 -sqrt(3)/2 sqrt(3)/2 ] V2 ]
' w ] 1 1 1 ] V3 ]
'
' [1x3 matrx] = [3x3 matrix] * [1x3 matrix]
'
'where L is a length constant, Vx, Vy, and w are the system translation velocity components, and the system
'angular velocity, and V1 is the wheel velocity vector at angle 0 degrees, V2 the wheel velocity vector at
'angle -120 degrees, and V3 the wheel velocity vector at 120 degrees.
'
'Solving this system for V1, V2, and V3 yields the following equations of motion:
'
' V1 = (2Vx + w) / 3
' V2 = (-Vx - SQR(3)*Vy + w) / 3
' V3 = (-Vx + SQR(3)*Vy + w) / 3
'
'(NOTE: These equations operate on the assumption that the magnitude of the desired velocity vector can be
'no greater than 127. That is, the hypotenuse of the triangle formed by the trans_x and trans_y variable
'cannot exceed 127. To ensure that this condition is met, one has to convert the rectangular
'coordinates (trans_x, trans_y) into polar coordinates (V_desired, theta), limit V_desired to 127, then
'back-calculate the new values of trans_x and trans_y based on the new value of V_desired and the already
'existent theta. The code that does this has been placed exactly before this large block of text.)
'
'(NOTE: UPDATE! The Basic Stamp doesn't like the math required to make the previous note a reality, so I
'am using a crude solution: I scale down all input values by 127*SQR(2) to ensure that the largest vector
'magnitude doesn't exceed 127.)
'
'The output from each equation (V1, V2, V3) is on the interval -127, 127], but the desired outputs,
'drill_1, drill_2, drill_3 are all on the interval [0, 254], so we compensate by setting drill_1, drill_2,
'and drill_3 to the shifted version of V1, V2, and V3:
'
' drill_1 = V1 + 127
' drill_2 = V2 + 127
' drill_3 = V3 + 127
'
'And that's it! Plug in all the variables, and we end up with the equations of motion that follow
'(note: fractions were expanded out to compensate for the integer based calculation done by the stamp):
'Motion equations
```

Thanks, and thanks for the sensor feedback. I did consider Ultasonics, but couldn’t hit on a scheme I thought would be reliable. Your info on the ultrasonics and performance at oblique angle confirms that I would have had a lot of problems. So- I’m using IR, very close proximity sensors, and a timing algorithm to detect differences in IR triggering in relation to angle of approach. I also have a mechanical switch backup plan- but I’d rather keep it clean with no real contact with the walls.

Thanks again for your reply. Billbo and Colin, your designs are both inspirational. Colin- I’ll put your method of joining chassis parts with bearing blocks in my mental toolkit- I’m new to vex so I appreciate seeing new uses for the parts. It’s amazing what can be done with, and learned from from, common creative constraints.

I’m glad I’m contending with 4-wheel math for holonomics rather than 3 though- much simpler. Thanks, trig.

As I mentioned earlier, I was working on getting this coded using EasyC v2.0. Well I finally got it working. The math is the same, the process is a little different, but it works. Oddly, the bot works smoother with the code done in MPLAB than it does with the code from EasyC. Anyway, I’m attaching the .hex, .bds and .ecp files from EasyC in the hopes someone else can use them. They are in a .zip file, so download and do what you will with them.

Kiwi Drive.zip (17.2 KB)

Kiwi Drive.zip (17.2 KB)

I noticed that your code uses a lot of custom c blocks to do the math. May I suggest using the “assignment” block, located in program flow in order to cut down on the labor. Perhaps it will work better as well.

That’s the help I’m looking for! My level of knowledge of EasyC is all based on my following the programming guide that came with 1.1 and my limited knowledge of C. So if I do things the hard way, it’s quite literally because I didn’t know any better. I will look into “assignment” blocks and see what I can do with them. I sure hope your right about it making the bot run better.

Logically speaking, the code should run the same whether I code it in MPLAB or EasyC. Realistically, I just need to figure out how to do it correctly in EacyC.

Thanks again!!

BTW, do you know if there are any detailed tutorials for EasyC 2.0? I found the programing guide for 1.1 quite helpful, but a little short on covering all options.

Indeed there is a very nice tutorial. Unlike most programs, the help file of easyC has been worked on quite a bit and is an excellent resource for any questions regarding the software. The file explains what every block and more. Whats real nice is if you have a problem with a specific block while you are trying to program with it, simply drag it into the program and hit “help”.

Oh, and there are some tutorials in the help file, but I believe the first few are the same as what came with your programming guide.