Isobeast Posted March 25, 2021 Share Posted March 25, 2021 Hello! I am trying to add a wheelie to a motorcycle script. Here is my control section. However, the bike takes off into the air if I ride on the rear wheel. How to fix it? Thanks a bunch for any help! control(key name, integer level, integer edge) { vector linear; vector angular; ... if (level & CONTROL_UP) { angular.y = 25.0; // wheelie up } if (level & CONTROL_DOWN) { angular.y = -25.00; // wheelie down } if (linear) llSetVehicleVectorParam(VEHICLE_LINEAR_MOTOR_DIRECTION, linear); if (angular) llSetVehicleVectorParam(VEHICLE_ANGULAR_MOTOR_DIRECTION, angular); } Link to comment Share on other sites More sharing options...
Profaitchikenz Haiku Posted March 25, 2021 Share Posted March 25, 2021 My best guess is you don't want to alter the angular velocity to give any vertical component, but instead rotate the vehicle appropriately? Maintain the velocity as a forward one (unless you're building a Scot-Squirrel or SunBeam/Indian in which case they did actually have the ability to reverse). 1 Link to comment Share on other sites More sharing options...
Isobeast Posted March 25, 2021 Author Share Posted March 25, 2021 56 minutes ago, Profaitchikenz Haiku said: My best guess is you don't want to alter the angular velocity to give any vertical component, but instead rotate the vehicle appropriately? Maintain the velocity as a forward one (unless you're building a Scot-Squirrel or SunBeam/Indian in which case they did actually have the ability to reverse). Yes, the script does have reverse and gear/throttle shifting. This is how it looks like: if (level & CONTROL_FWD) { if (edge & CONTROL_FWD) { if (throttle < 100) throttle += 10; throttlePress = 0; } else if (++throttlePress == 10) { throttlePress = 0; if (throttle < 100) throttle += 10; } } if (level & CONTROL_BACK) { if (edge & CONTROL_BACK) { if (throttle > -30) throttle -= 10; throttlePress = 0; } else if (++throttlePress == 10) { throttlePress = 0; if (throttle > -30) throttle -= 10; } } Link to comment Share on other sites More sharing options...
Isobeast Posted March 25, 2021 Author Share Posted March 25, 2021 (edited) 2 hours ago, Profaitchikenz Haiku said: Maintain the velocity as a forward one I did as you recommended and it looks very good. This is my first motorcycle, and I am not sure "to shift, or not to shift" gears/throttle. Another problem is that the speed of rotation of the wheels depends on the throttle valve. And if I remove the throttling, how then to calculate the speed of rotation of the wheels, depending on what? if (throttle) { llSetVehicleVectorParam(VEHICLE_LINEAR_MOTOR_DIRECTION, < fwd * (throttle * 0.01), 0, 0 > ); llSetLinkPrimitiveParamsFast(WHEEL_PRIM, [PRIM_OMEGA, WHEEL_AXIS, throttle * 0.2, 1, PRIM_LINK_TARGET, WHEEL_PRIM_2, PRIM_OMEGA, WHEEL_AXIS, throttle * 0.2, 1]); } New wheelie: if (level & CONTROL_UP) { linear.x = 20.0; angular.y = 25.0; } if (level & CONTROL_DOWN) { linear.x = -1.00; angular.y = -25.00; } Addition: I tried to adjust the rotation of the wheels depending on the speed, but when reversing, the wheels continue to rotate forward. float speed = llVecMag(llGetVel()); llSetLinkPrimitiveParamsFast(PROP_PRIM, [PRIM_OMEGA, PROP_AXIS, speed, 1, PRIM_LINK_TARGET, PROP_PRIM_2, PRIM_OMEGA, PROP_AXIS, speed, 1]); Edited March 25, 2021 by Isobeast Link to comment Share on other sites More sharing options...
Profaitchikenz Haiku Posted March 25, 2021 Share Posted March 25, 2021 (edited) llVecMag will remove any negative quantities in the velocity vector. (* There is a better way of putting this) You will have to find a way of working out if you are going in reverse and use the sign of that in the PRIM_OMEGA speed value. i.e integer direction = 1; but if you are going backwards direction = -1, and so use direction * speed as the value for prim_omega * One, some, or all of my proof readers will be along once the market place crash has stopped drawing them all to look and goggle, and hopefully give you a more accurate answer than I can. Edited March 25, 2021 by Profaitchikenz Haiku 1 Link to comment Share on other sites More sharing options...
Isobeast Posted March 25, 2021 Author Share Posted March 25, 2021 8 minutes ago, Profaitchikenz Haiku said: llVecMag will remove any negative quantities in the velocity vector. (* There is a better way of putting this) You will have to find a way of working out if you are going in reverse and use the sign of that in the PRIM_OMEGA speed value. i.e integer direction = 1; but if you are going backwards direction = -1, and so use direction * speed as the value for prim_omega * One, some, or all of my proof readers will be along once the market place crash has stopped drawing them all to look and goggle, and hopefully give you a more accurate answer than I can. Thank you! Wondering how to determine the direction +/- ... and is it possible to keep the throttle here and does it make any sense? Link to comment Share on other sites More sharing options...
Profaitchikenz Haiku Posted March 25, 2021 Share Posted March 25, 2021 (edited) 9 minutes ago, Isobeast said: Wondering how to determine the direction +/- llGetLocalRot(backside) is your friend. Quite seriously though, you will usually be going forwards so direction is 1 by default, you will only be going backwards if you have either a) selected reverse gear - in which case you explicity set it to -1 b) have ridden into and are rebounding from an obstacle. I'd not bother rotating the wheels in this case Edited March 25, 2021 by Profaitchikenz Haiku 1 Link to comment Share on other sites More sharing options...
animats Posted March 25, 2021 Share Posted March 25, 2021 I have a script in each wheel which manages its rotation, depending on the velocity in the local frame. But you don't have to. speed is how fast you're going. > 0 is forward. rate is how fast the wheel should turn at that speed. vector vehdir = <1.0,0.0,0.0>*llGetRootRotation(); // global direction of vehicle float speed = vehdir*llGetVel(); // speed in fwd direction // Convert to wheel rotation rate in radians/sec float rate = speed / (WheelDiameter*PI); You need to put in a WheelDiameter of your own. Useful hints: On each update cycle, send a new omega to the wheel only if it's changed by 10% or more, or it's stopped. Otherwise you send too many updates to the viewer and the changes may not look good. Limit rate to 10 or so. Turning faster than that, it doesn't look good given the frame rates SL can achieve. Check for near 0 and set to 0 rate. Slowly turning wheels while stopped look silly. The problem of rotating both the front forks and the wheel is left as an exercise for the student. 1 Link to comment Share on other sites More sharing options...
Isobeast Posted March 25, 2021 Author Share Posted March 25, 2021 (edited) 2 hours ago, animats said: The problem of rotating both the front forks and the wheel is left as an exercise for the student. Thanks a lot! 😊 Now both wheels are turning correctly! float WheelDiameter = 0.71403; vector vehdir = <1.0,0.0,0.0> * llGetRootRotation(); // Global direction of vehicle float speed = vehdir * llGetVel(); // Speed in fwd direction // Convert to wheel rotation rate in radians/sec float rate = speed / (WheelDiameter * PI); llSetLinkPrimitiveParamsFast(PROP_PRIM, [PRIM_OMEGA, PROP_AXIS, rate * 5, 1, PRIM_LINK_TARGET, PROP_PRIM_2, PRIM_OMEGA, PROP_AXIS, rate * 5, 1]); Only it is not clear how to limit this part by 10%? 🤔 2 hours ago, animats said: On each update cycle, send a new omega to the wheel only if it's changed by 10% or more, or it's stopped. Otherwise you send too many updates to the viewer and the changes may not look good. Edited March 25, 2021 by Isobeast Link to comment Share on other sites More sharing options...
animats Posted March 26, 2021 Share Posted March 26, 2021 9 hours ago, Isobeast said: Thanks a lot! 😊 Now both wheels are turning correctly! float WheelDiameter = 0.71403; vector vehdir = <1.0,0.0,0.0> * llGetRootRotation(); // Global direction of vehicle float speed = vehdir * llGetVel(); // Speed in fwd direction // Convert to wheel rotation rate in radians/sec float rate = speed / (WheelDiameter * PI); llSetLinkPrimitiveParamsFast(PROP_PRIM, [PRIM_OMEGA, PROP_AXIS, rate * 5, 1, PRIM_LINK_TARGET, PROP_PRIM_2, PRIM_OMEGA, PROP_AXIS, rate * 5, 1]); Only it is not clear how to limit this part by 10%? 🤔 Save the last value you set. If the new value is within 10% of the old, and is not zero, don't change the speed of the wheel. 1 Link to comment Share on other sites More sharing options...
Isobeast Posted March 26, 2021 Author Share Posted March 26, 2021 6 hours ago, animats said: Save the last value you set. If the new value is within 10% of the old, and is not zero, don't change the speed of the wheel. Thanks again! But I'm sure that I'm doing everything wrong ... rate++ if (rate >= rate / 10) { llSetLinkPrimitiveParamsFast(PROP_PRIM, [PRIM_OMEGA, PROP_AXIS, rate * 5, 1, PRIM_LINK_TARGET, PROP_PRIM_2, PRIM_OMEGA, PROP_AXIS, rate * 5, 1]); } Link to comment Share on other sites More sharing options...
Profaitchikenz Haiku Posted March 26, 2021 Share Posted March 26, 2021 Try if ( llFabs(rate - oldRate) > rate / 10) You will obviously have to assign values to oldRate prior to this test 1 Link to comment Share on other sites More sharing options...
Isobeast Posted March 26, 2021 Author Share Posted March 26, 2021 (edited) 6 hours ago, Profaitchikenz Haiku said: Try if ( llFabs(rate - oldRate) > rate / 10) You will obviously have to assign values to oldRate prior to this test Thanks a lot! And how to assign these values? Will I need to make a list? Edited March 26, 2021 by Isobeast Link to comment Share on other sites More sharing options...
Profaitchikenz Haiku Posted March 26, 2021 Share Posted March 26, 2021 (edited) Look for where rate is declared and declare oldRate just below it, as the same type. Where you see rate being assigned a value, such as rate++; or rate = 0.0; immediately before that line, add oldRate = rate; Instead of rate++, I suggest you determine a minimum speed increase and use that to increment or decrement rate ie instead of rate++ use rate += 0.5 or instead of rate-- use rate -= 0.5 Edited March 26, 2021 by Profaitchikenz Haiku 1 Link to comment Share on other sites More sharing options...
Profaitchikenz Haiku Posted March 26, 2021 Share Posted March 26, 2021 In passing, don't forget that in the expression 2 hours ago, Isobeast said: if ( llFabs(rate - oldRate) > rate / 10) rate is being used as a divisor, so in the special case where you have come to a stop, don't try testing to see if the change is 10%, just do it. Similarly, when starting from standstill, don't bother with the test, just apply the rate This then leads you to the combined expression if( rate == 0.0 || oldRate == 0.0 || (llFabs(rate - oldRate) > rate / 10.0) ) // do it else // ignore it The order in which those individual tests are made ensures that the division won't occur if rate is zero, because the test for zero is made first of all, and the logical OR || ensures a true result at that point, no further evaluation of the expression should occur. 1 1 Link to comment Share on other sites More sharing options...
Quistess Alpha Posted March 27, 2021 Share Posted March 27, 2021 maybe I'm just tired, but shouldn't it only matter if 0 is a divisor? (x/10) will always produce a valid result whereas (10/x) could throw out math errors. 1 Link to comment Share on other sites More sharing options...
Profaitchikenz Haiku Posted March 27, 2021 Share Posted March 27, 2021 7 hours ago, Quistessa said: maybe I'm just tired, but shouldn't it only matter if 0 is a divisor? I thought so at first, but then I realised the two special cases of the vehicle either stopping or else starting from rest were both instances where you would want to start or stop a rotation regardless of the amount it had changed by, so came up with a one-liner. 1 Link to comment Share on other sites More sharing options...
Quistess Alpha Posted March 27, 2021 Share Posted March 27, 2021 (edited) 15 hours ago, Profaitchikenz Haiku said: The order in which those individual tests are made ensures that the division won't occur if rate is zero, because the test for zero is made first of all, and the logical OR || ensures a true result at that point, no further evaluation of the expression should occur. Unfortunately I just remembered : Quote Note: Unlike most other languages that use the C-style && and || operators, both operands are always evaluated. For example, if (TRUE || 1/0) llSay(PUBLIC_CHANNEL, "Aha!"); will cause a Math Error rather than say "Aha!" http://wiki.secondlife.com/wiki/LSL_Operators I think this means it's reasonable practice to use nested if statements for &&. || is a bit more tricky, but you could probably do something similar to 'most other languages' if you really needed to with some clever jumps. Edited March 27, 2021 by Quistessa 1 Link to comment Share on other sites More sharing options...
Isobeast Posted March 27, 2021 Author Share Posted March 27, 2021 15 hours ago, Profaitchikenz Haiku said: In passing, don't forget that in the expression rate is being used as a divisor, so in the special case where you have come to a stop, don't try testing to see if the change is 10%, just do it. Similarly, when starting from standstill, don't bother with the test, just apply the rate This then leads you to the combined expression if( rate == 0.0 || oldRate == 0.0 || (llFabs(rate - oldRate) > rate / 10.0) ) // do it else // ignore it The order in which those individual tests are made ensures that the division won't occur if rate is zero, because the test for zero is made first of all, and the logical OR || ensures a true result at that point, no further evaluation of the expression should occur. Perfect! Thanks for not leaving me alone with my problem!! 🚲👍🏻👍🏻👍🏻 ( I hope I did everything right. One more question. How to display the value of the rate in the chat? I wanted to know how it changes and tried llOwnerSay(rate); but it turns out "Function call .." ) That's what I got .. may be useful to someone float WheelDiameter = 0.71403; vector vehdir = <1.0,0.0,0.0> * llGetRootRotation(); // Global direction of vehicle float speed = vehdir * llGetVel(); // Speed in fwd direction // Convert to wheel rotation rate in radians/sec float rate = speed / (WheelDiameter * PI); float oldRate = speed / (WheelDiameter * PI); oldRate = rate; rate += 0.5; if( rate == 0.0 || oldRate == 0.0 || (llFabs(rate - oldRate) > rate / 10.0) ) { llSetLinkPrimitiveParamsFast(PROP_PRIM, [PRIM_OMEGA, PROP_AXIS, rate * 5, 1, PRIM_LINK_TARGET, PROP_PRIM_2, PRIM_OMEGA, PROP_AXIS, rate * 5, 1]); } Link to comment Share on other sites More sharing options...
Profaitchikenz Haiku Posted March 27, 2021 Share Posted March 27, 2021 (edited) 4 hours ago, Quistessa said: Yes, you're right on both counts, there wasn't the risk of division by zero in my initial lines, I guess the tiredness is contagious. I played around with that operator example you pointed to because I was quite flabbergasted I had a) never known that about LSL, and b) never yet got tripped up by it. Maybe I need to get out more. I'm going to retire from answering request for help on this forum until I've worked out if I really am on the way downhill or if this is just a bad-luck-streak-in-dancing-school thing. Edited March 27, 2021 by Profaitchikenz Haiku 1 Link to comment Share on other sites More sharing options...
Isobeast Posted March 27, 2021 Author Share Posted March 27, 2021 Is there really a mistake somewhere? everything seems to work as it should ... 🤔 Link to comment Share on other sites More sharing options...
Isobeast Posted March 27, 2021 Author Share Posted March 27, 2021 1 hour ago, Profaitchikenz Haiku said: I'm going to retire from answering request for help on this forum until I've worked out if I really am on the way downhill or if this is just a bad-luck-streak-in-dancing-school thing. Please do not! 😭 2 Link to comment Share on other sites More sharing options...
Isobeast Posted March 28, 2021 Author Share Posted March 28, 2021 (edited) Back to the main topic, is there any other way to make the wheelie without changing linear/angular, for example, rotating the root prim and the entire linkset? Maybe I can use llApplyImpulse for this? Edited March 28, 2021 by Isobeast Link to comment Share on other sites More sharing options...
Quistess Alpha Posted March 28, 2021 Share Posted March 28, 2021 You /can/ try mixing regular physics manipulations with vehicle physics things, but the documentation advises against it. If I were to have a play at it though, I would try llRotLookAt() 1 Link to comment Share on other sites More sharing options...
Mollymews Posted March 28, 2021 Share Posted March 28, 2021 8 hours ago, Isobeast said: Back to the main topic, is there any other way to make the wheelie without changing linear/angular, for example, rotating the root prim and the entire linkset? Maybe I can use llApplyImpulse for this? is not a good idea to mix them up doing wheelies with angular motor can be done fairly easily. In your OP script you are applying way to much direct power. The better way is to apply some multiple of the current motor the original Linden motorcycle script is a good source to look at how linear and angular motors can work quite well together a modified version of this script is here. the mods are more about showing what happens on region crossings. But the basics of the Linden motorcycle engine are preserved 1 Link to comment Share on other sites More sharing options...
Recommended Posts
Please take a moment to consider if this thread is worth bumping.
Please sign in to comment
You will be able to leave a comment after signing in
Sign In Now