-
Posts
3,650 -
Joined
-
Last visited
Content Type
Profiles
Forums
Developer Articles
KSP2 Release Notes
Everything posted by Starwhip
-
Massive psychological experiment in the KSP forums.
Starwhip replied to gmpd2000's topic in The Lounge
This is a very, very hard decision. Logic dictates that you pull the lever: fewer people die. But then you feel that by doing something, you made the choice that kills someone. But if you don't pull the lever, more people die. Almost as bad as the Miligram Experiment... -
A few tips: Write up a checklist and keep it with you at all times. It should look like this: [] Parachutes [] Batteries [] Docking Ports [] Solar Panels [] RCS Fuel [] RCS Thrusters [] Engine Fuel [] Jet Fuel [] Intakes [] Engines [] Action Groups [] Staging [] Landing Gear [] Crew The most frustrating thing is to forget something while building. A second mission-specific checklist can also be written from multi-contract missions, but I can't help you there without having your contracts. Other than that, just keep experimenting! You'll eventually settle into a design strategy you like. Welcome to the forum!
-
Holy cow: #include "WPILib.h" #include <thread> #include <tuple> #include <cmath> /* These are pre-processing directives, the compiler will find in your code all these names, and replace them with the numbers listed beside them. */ #define frontLeftChannel 0 //the port for the front left drive motor #define frontRightChannel 1 //the port for the front right drive motor #define rearLeftChannel 2 //the port for the back left drive motor #define rearRightChannel 3 //the port for the back right drive motor #define liftChannel 4 //the port for the main lift motor #define rollerOneChannel 6 #define rollerTwoChannel 7 #define rightRollerSolenoidChannel 0 #define leftRollerSolenoidChannel 1 #define rightForkSolenoidChannel 2 #define leftForkSolenoidChannel 3 #define joystickDriveChannel 0 //what position in the controller array is the drive controller #define joystickArmChannel 1 //what position in the controller array is the lift controller #define joystickThreshold 0.15 //the "dead" zone of the controller #define joystickLimit 1.0 // % of range (1.0 = 100%, .75 = 75% etc.) #define encFLreverse false; //Reverse the Front Left Encoder #define encBLreverse false; //Reverse the Back Left Encoder #define encFRreverse false; //Reverse the Front Right Encoder #define encBRreverse false; //Reverse the Back Right Encoder #define encoderFLchannelA 0; #define encodingType Encoder::k4X //idk if this even works but ima try it #define JOYZCAPABLE false //are you using a z-axis capable controller (in our case the Logitech Log 3D pro) /*____________________________________HUGE PROGRAMMING NOTE!!!_____________________________________ * TO DEPLOY TO THE roboRIO, YOU MUST RIGHT CLICK ON THE BUILD.XML FILE, * AND SELECT "RUN AS ANT BUILD". * ECLIPSE NO LONGER GIVES THE OPTION TO DEPLOY AS C++ CODE!!! */ //Autonomous turning does not work as of now. class Robot: public SampleRobot { RobotDrive robotDrive; // robot drive system Talon liftMotor; // the lift motor controller //Talon liftTwo; Talon rollerOne; Talon rollerTwo; Joystick driveStick; // only joystick Joystick armStick; //Not anymore, you stupid comment! // why are you so mean to me? -driveStick comment Encoder encoderFL; //Front Left Encoder Encoder encoderBL; //Back Left Encoder Encoder encoderFR; //Front Right Encoder Encoder encoderBR; //Back Right Encoder Encoder encoderLift; //Take a wild guess AnalogInput bottomLimitSwitch; //limit switch for the bottom bar AnalogInput topLimitSwitch; //limit switch for the top bar AnalogInput toteLimitSwitch; Solenoid rightArm; Solenoid leftArm; Solenoid rightFork; Solenoid leftFork; int encoderPorts[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; int FLdis; int FRdis; int BLdis; int BRdis; int Auton = 0; int AutonChoice = 1; int rollerOneMult = 1; int rollerTwoMult = -1; float driveStick_x = 0; //the first controller x axis value float driveStick_y = 0; //the first controller y axis value float driveStick_z = 0; //the first controller z axis value float armStick_y = 0; // the second controller y axis value float attackRotRate = 0.75; //This is the rotation rate when using the buttons float slider = 0; // i have no clue what this is supposed to be float currAvgPosition; float startPosition; float rollerSpeed = 1; bool throttleEnabled = true; //True means throttle is enabled, false not... bool rotationLock = true; //True means that button 2 is needed for rotation. bool defDriveMode = true; //True defaults to analog drive bool topSwitchPressed = false; bool bottomSwitchPressed = false; bool rollerArmsOut = false; double wheelDiam = 5.98; //Inches public: //_____________________INITIALIZATION ROUTINES__________________________ Robot() : robotDrive( frontLeftChannel, rearLeftChannel, frontRightChannel, rearRightChannel), // these must be initialized in the same order liftMotor(liftChannel), // as they are declared above. //liftTwo(backupLiftChannel), rollerOne(rollerOneChannel), rollerTwo(rollerTwoChannel), driveStick(joystickDriveChannel), armStick(joystickArmChannel), encoderFL(encoderPorts[0],encoderPorts[1], false, encodingType), encoderBL(encoderPorts[2], encoderPorts[3], false, encodingType), encoderFR(encoderPorts[4], encoderPorts[5], true, encodingType), encoderBR(encoderPorts[6], encoderPorts[7], true, encodingType), encoderLift(encoderPorts[8], encoderPorts[9], false, encodingType), bottomLimitSwitch(0), topLimitSwitch(1), toteLimitSwitch(2), rightArm(rightRollerSolenoidChannel), leftArm(leftRollerSolenoidChannel), rightFork(rightForkSolenoidChannel), leftFork(leftForkSolenoidChannel) { robotDrive.SetExpiration(0.1); robotDrive.SetInvertedMotor(RobotDrive::kFrontLeftMotor, false);// do not invert the left side motors robotDrive.SetInvertedMotor(RobotDrive::kRearLeftMotor, false); robotDrive.SetInvertedMotor(RobotDrive::kFrontRightMotor, true);// invert the right side motors robotDrive.SetInvertedMotor(RobotDrive::kRearRightMotor, true);// you may need to change or remove this to match your robot } float map(float x, float in_min, float in_max, float out_min, float out_max)//*Dalek Voice* EXPLAIIIIIIIIIIN { //_____________________FLOAT MAPPING__________________________ return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;//*Dalek Voice* EXPLAIIIIIIIIIIIIIIIIIIIIIIN //Takes in a variable, and variable range, spits out new value } float degToRad(float deg){ return (deg*M_PI) / 180; } float radToDeg(float rad){ return (rad*180)/M_PI; } void rollerSpin(bool in) { if(in){ rollerOne.SetSpeed(rollerSpeed); //Rollers IN rollerTwo.SetSpeed(-rollerSpeed); } else{ rollerOne.SetSpeed(-rollerSpeed); //Rollers OUT rollerTwo.SetSpeed(rollerSpeed); } } void rollerArms(bool extend){ if(extend){ leftArm.Set(true); Wait(.05); rightArm.Set(true); rollerArmsOut = true; } else{ rightArm.Set(false); Wait(.05); leftArm.Set(false); rollerArmsOut = false; } } void joySettings() { if (driveStick.GetRawButton(7)) { //Enables analog default drive defDriveMode = true; } else if (driveStick.GetRawButton(8)) { //Enables precision drive defDriveMode = false; } if (driveStick.GetRawButton(9)) { //Enables Rotation Lock Mode rotationLock = true; } else if (driveStick.GetRawButton(10)) { //Disables rotation lock rotationLock = false; } if (driveStick.GetRawButton(11)) { //Enables throttle throttleEnabled = true; } else if (driveStick.GetRawButton(12)) { //Disables Throttle (100%) throttleEnabled = false; } } void virtualDriveStick(float l_angle,float l_rot,float l_mag,float l_throttle){ //Angle 0 is rightmost, PI is rightmost slider = l_throttle; //Bad naming convention is bad... Sets throttle driveStick_x = l_mag * cos(l_angle); //X axis of "joystick" driveStick_y = l_mag * sin(l_angle); //Y axis of "joystick" driveStick_z = l_rot; //Rotation Zed Axis } void killMotors(){ virtualDriveStick(0,0,0,0); //No drive or rotation of "joystick" drive(); liftControl(0); } float getAvgEncoder(Encoder enc1, Encoder enc2, Encoder enc3, Encoder enc4){ //Average encoder value. So far unused. //and that makes me sad. return (enc1.GetDistance()+enc2.GetDistance()+enc3.GetDistance()+enc4.GetDistance())/4; } std::tuple<double,double> getRobotDis(){ //Gets your x and y components of translation double enc1Dis = encoderFL.GetDistance(); //FL double enc2Dis = encoderBL.GetDistance(); //BL double enc3Dis = encoderFR.GetDistance(); //FR double enc4Dis = encoderBR.GetDistance(); //BR if(!encoderFL.GetDirection()){ //Lots of complicated stuff to get direction of encoders. enc1Dis *= -1; //Encoder.GetDirection() returns true or false, false is default and "backwards". } if(!encoderBL.GetDirection()){ enc2Dis *= -1; } if(!encoderFR.GetDirection()){ enc3Dis *= -1; } if(!encoderBR.GetDirection()){ enc4Dis *= -1; } double robotVector_x = (-(enc1Dis+enc2Dis)+enc3Dis+enc4Dis)*cos(M_PI/4); //YAY, summations double robotVector_y = (-(enc2Dis+enc4Dis)+enc3Dis+enc1Dis)*sin(M_PI/4); return std::make_tuple(robotVector_x,robotVector_y); //WPI lib says hi. C++ doesn't support tuples by default } void RoboInit() { double wheelCirc = wheelDiam * M_PI; double disPerTick = wheelCirc / 1440; //Inches (I's small) //not compared to the size of an electron //Encoder encoderList = {encoderFL, encoderBL, encoderFR, encoderBR}; //at least we tried encoderFL.SetDistancePerPulse(disPerTick); //So that encoders return inches encoderBL.SetDistancePerPulse(disPerTick); encoderFR.SetDistancePerPulse(disPerTick); encoderBR.SetDistancePerPulse(disPerTick); //close solenoids } void precisionControl() { //_______________________________PRECISION DRIVE MODE_____________________________ int povAngle = driveStick.GetPOV(0); if(povAngle == -1){ killMotors(); } if (driveStick.GetRawButton(3)) { //Left Rotation driveStick_z = -1; } else if (driveStick.GetRawButton(4)) { //Right Rotation driveStick_z = 1; } else { //No Rotation driveStick_z = 0; } virtualDriveStick(degToRad(povAngle),driveStick_z,1,1); } void analogControl() { //_____________________________________NORMAL DRIVE MODE (ANALOG)_______________________________ //Get Joystick Raw Values driveStick_x = driveStick.GetX(); driveStick_y = driveStick.GetY(); //Written to account for lack of Logitec 3DPro joystick (Z-axis rotation of joystick) //could be redone so that it takes into account any z-axis capable joystick (rename the declaration more or less) if (JOYZCAPABLE) { if (throttleEnabled) { //CUSTOM CONFIG If enabled: throttle is usable slider = map(driveStick.GetRawAxis(3), -1, 1, 1, 0);// how is the out min bigger than the out max? } else { //Locks throttle to 100% slider = 1; } driveStick_z = driveStick.GetZ(); //map(x, in_min, in_max, out_min, out_max) if (fabs(driveStick_z) < joystickThreshold || (!driveStick.GetRawButton(2) && rotationLock) || driveStick.GetRawButton(1)) { //why are we checking for button 1? Accidental turning?? if so then the check for 2 is redundant driveStick_z = 0; } } else { //we might want to redo all of this so that the button input is saved in a var that way we can use controllers other than ours if (driveStick.GetRawButton(4)) { //if button 4 is pressed (left?) turn (left?) driveStick_z = -attackRotRate; } else if (driveStick.GetRawButton(5)) { //if button 5 is pressed (right?) turn (right?) driveStick_z = attackRotRate; } else { driveStick_z = 0; //you press nothing... NATHING! } slider = map(driveStick.GetRawAxis(2), -1, 1, 1, 0); //wat? i is confuzed by slider } //Threshold Value Setting if (fabs(driveStick_x) < joystickThreshold || driveStick.GetRawButton(1)) { // if the x value is inside of the "dead" zone or you are holding the trigger set the x value to 0 driveStick_x = 0; } if (fabs(driveStick_y) < joystickThreshold || driveStick.GetRawButton(1)) { // if the y value is inside of the "dead" zone or you are holding the trigger set the y value to 0 driveStick_y = 0; } } void liftControl(float yAxis) { //__________________________LIFT_SECTION_OF_MAIN_LOOP______________________ topSwitchPressed = (topLimitSwitch.GetValue() < 2048) ? false : true; bottomSwitchPressed = (bottomLimitSwitch.GetValue() < 2048) ? false : true; if((topSwitchPressed && yAxis >= 0) || (fabs(yAxis) <= joystickThreshold) || (bottomSwitchPressed && yAxis <= 0)){ liftMotor.SetSpeed(0); } else{ liftMotor.SetSpeed(yAxis); } } void liftArm(float speed, float time){ liftControl(speed); Wait(time); killMotors(); } void rollerArmSolenoidControl(){ if (armStick.GetRawButton(7) && toteLimitSwitch.GetValue() < 2048){ //Retract Roller Arms! rollerArms(false); } else if (armStick.GetRawButton(6)){ //Extend Roller Arms! rollerArms(true); } if (armStick.GetRawButton(1) && rollerArmsOut){ //Trigger: Used to suck in totes rollerSpin(true); } else if (armStick.GetRawButton(3) && rollerArmsOut){ //Middlemost button of joystick. Spits out totes rollerSpin(false); } } void forkArms(bool extend){ if(extend){ rightFork.Set(true); leftFork.Set(true); } else{ rightFork.Set(false); leftFork.Set(false); } } void forkArmSolenoidControl(){ if(armStick.GetRawButton(11)){ forkArms(true); } else if(armStick.GetRawButton(10)){ forkArms(false); } } void logOutput() { //outputs to the smart dashboard so we can see real-time values. SmartDashboard::PutNumber("Joystick X ", double(driveStick_x)); SmartDashboard::PutNumber("Joystick Y ", double(driveStick_y)); SmartDashboard::PutNumber("Joystick Z ", double(driveStick_z)); SmartDashboard::PutNumber("Throttle ", double(slider)); //SmartDashboard::PutNumber("Top Limit ", double(topLimitSwitch.GetValue())); //SmartDashboard::PutNumber("Bottom Limit", double(bottomLimitSwitch->Get())); } void drive(){ //Instead of copy-pasting below robotDrive.MecanumDrive_Cartesian(driveStick_x * joystickLimit * slider, driveStick_y * joystickLimit * slider, driveStick_z * joystickLimit * slider); //Actually do the moving stuff } void driveAuto(float dis,float angle,float speed,float rot){ //Autopilot drive system. Takes a distance at angle from front of robot, a speed, and a rotation value virtualDriveStick(angle,rot,speed,1); //Throttle is 1 by convention. Speed controls speed. float dis_x = dis*cos(degToRad(angle)); //Distance to move (X-axis) float dis_y = dis*sin(degToRad(angle)); //Other distance (Y-axis) double vec_x; //Encoder value X double vec_y; //Encoder value Y drive(); //ENGAGE MOTORS! while(vec_x >= dis_x || vec_y >= dis_y){ //If it's gone too far... std::tie(vec_x,vec_y) = getRobotDis(); //Update distance } killMotors(); //NO JOYSTICK FOR JU } void driveModeSelect() { //___________________________DRIVE_SECTION_OF_MAIN_LOOP_______________________ //if you are holding the trigger use precision drive, else use regular drive // Use the joystick X axis for lateral movement, Y axis for forward movement, and Z axis for rotation. // This sample does not use field-oriented drive, so the gyro input is set to zero. if (defDriveMode) { //Analog Drive is Default if (!driveStick.GetRawButton(1)) { //"Button 1" is the trigger. analogControl();//Button 2 is for Z-Rotation Lock... And think about it: // How do you hit the thumb button if you're using your thumb on the hat switch? } else { precisionControl(); } } else { if (!driveStick.GetRawButton(1)) { precisionControl(); } else { analogControl(); } } drive(); } void OperatorControl() { robotDrive.SetSafetyEnabled(false); //no safety for you while (IsOperatorControl() && IsEnabled()) { joySettings(); driveModeSelect(); liftControl(armStick.GetY()); rollerArmSolenoidControl(); forkArmSolenoidControl(); logOutput(); Wait(0.005); // wait 5ms to avoid hogging CPU cycles } } void Autonomous() { while(IsAutonomous() && IsEnabled()) { if(Auton != 1 && Auton != 2 && Auton != 3 && Auton != 4){ Auton = 1; } switch (Auton){ case 1: driveAuto(140,90,0.75,0); //Go to auto zone break; case 2: liftArm(0.75,0.5); //Lift up tote driveAuto(0,0,0.75,90); //Rotate 90 degrees Wait(0.1); driveAuto(140,90,0.75,0); //Go to auto zone break; case 3: forkArms(true); //Extend fork Wait(0.5); liftArm(0.75,0.5); //Lift tote driveAuto(0,0,0.75,-90); //Rotate left 90 Wait(0.1); driveAuto(140,90,0.75,0); //Go to auto zone break; case 4: forkArms(true); //Extend fork Wait(0.5); liftArm(0.75,1.5); //Raise arm and pick up trash can driveAuto(24,90,0.75,0); //Drive forward 2 feet to tote Wait(0.1); liftArm(-0.75,1.0); //Lower arm, drop trash can on tote forkArms(false); //Retract fork Wait(0.5); driveAuto(8,90,0.75,0); //Drive forward 8 inches Wait(0.1); liftArm(-0.75,1.5); //Lower arm under tote liftArm(0.75,1.5); //Raise arm, pick up both driveAuto(0,0,0.75,-90); //Rotate 90 left Wait(0.1); driveAuto(140,90,0.75,0); //Go to parking zone break; } } } }; START_ROBOT_CLASS(Robot); //Initializes the class so the robot actually does stuff Five Hundred and Twelve lines of code. And all of it yet untested! GO BUILD TEAM! Seriously, the programming team never gets a chance to test anything... competition should be interesting. It should now be able to to whatever the heck we want it to: just a couple lines and you've got another autonomous program!
-
Steering Issues
Starwhip replied to Commissioner Tadpole's topic in KSP1 Gameplay Questions and Tutorials
A few things: Do these rockets have a Stayputnik core? Those no longer have SAS. It could be part clipping. Try looking around for that. It could also be too much control authority. Cut back on torque and winglets, see how it flies. -
Methinks it's a trim problem: Try hitting the key combo "Alt" + "X" to disable all trim. Are you using mods, namely MechJeb? It's autopilot is very generous with RCS thrusters.
-
I Remember... (A Thread for Early KSP Nostalgia)
Starwhip replied to macdjord's topic in KSP1 Discussion
I remember the old umbrella antenna... And the bad SAS hold. R.I.P. Avionics Nosecone! -
[11/26/15 Update] Say Hello to the Light-Green Group!
Starwhip replied to Endersmens's topic in Kerbal Network
Four-forty-two! Four-forty-two! Soon, my brethren... -
Renaming from the Tracking Station or Map Mode
Starwhip replied to BlkBltChemie's topic in KSP1 Discussion
Heh.... Anyway, when was this added?! I want to know! We shall search the backwaters of the release logs! -
Nein! (How do you guys do that!? ) Um, KasperVLD?
-
Ah.... um.... what?!
-
Running into KSP players in the real world.
Starwhip replied to NecroBones's topic in KSP1 Discussion
One of my teachers last year plays, or played, KSP. I don't know which anymore... But in extracurricular scenarios, nobody has ever mentioned it yet. -
Um, what? I say zekes!
-
Have a +1! 1
-
Something's not quite right with my VAB.
Starwhip replied to Whirligig Girl's topic in KSP1 Discussion
Is that the TARDIS mod? I heard something about a mod for that a while back. -
The Return of the Lost (Macey Dean series inspired)
Starwhip replied to Voyager55's topic in KSP Fan Works
This is great! And "amateur artwork"? It's much better than amateur! Keep it up, I like it. -
Something's not quite right with my VAB.
Starwhip replied to Whirligig Girl's topic in KSP1 Discussion
*cracks up* Very nice. Who else sees it? XD -
Well, just those two are not all that bad, but even simple mods may be unavailable for some. Be wary about that.
-
Have you ever met anyone who thinks that Apollo was fake?
Starwhip replied to FishInferno's topic in The Lounge
This is uncannily evenly matched... -
Ship with a working stock elevator loading bay landed on minmus.
Starwhip replied to Kianykin's topic in KSP1 Discussion
Incredible! Simply incredible! Rep for you, sir! -
Run Unit Tests
Starwhip replied to Renegrade's topic in KSP1 Technical Support (PC, modded installs)
It's always been there, as far as I know. Though it's so small that most people never notice it. -
Floor 1076: The room is pitch black apart from the light from the stairwell across the room. You can hear absolutely nothing. With your spine tingling you sprint to the stairwell, and as you look over your shoulder you swear you see something moving in the darkness...
-
Hello, glad to see you!
-
Fingerprints are definitely less "secure" as they can't be changed, yes, but not *everyone* has access to your fingerprints, while the ENTIRE INTERNET could possibly get a picture of your face. Provided you actually use your face. I'd use a book or something.