Toastie Posted August 20, 2010 Posted August 20, 2010 Dear All, I have uploaded a video on YouTube showing some LEGO trains equipped with RCX PBricks running on one larger stretch of track: Control is via IR messaging from a PC program talking/listening to the LEGO IR tower traffic. A simple ID/databyte message exchange protocol adresses individual trains on the track (or all). The track is powered with 9 ... 18V DC, as one sees fit. The PBricks are all RCX1.0, pick up power from the tracks via modified 9V trains motors and deliver power back to the motors. The RailBrick Journal Issue 3 (Page 44 and up) has some more information. The program running on the RCX and some other details are also available on the RailBricks website (see building instruction section, Diesels, GP40_RCX). It's up to you what the trains do, just program that into the RCX. I am simple minded, so power level setting 0 ... +/-7 (compatible with the 9V speed regulator, I love compatibility), some power level ramping (internally on the RCX, which allows 25 power level settings for each direction, looks more realistic when going from 0 to 5), head light on/off, some sound generation, and PID speed control (that IS fun!) is what I came up with. I am working on getting the NXT PBrick to be of any value here ... Rock on, Thorsten Quote
JopieK Posted August 27, 2010 Posted August 27, 2010 How would you use PID control on a LEGO train then?! It is kind of strange for a train to use PID, it is more suitable for robots isn't it?! Update: after seeing the nice video, I understand what you mean, but that is not PID, it is more like the servo principal. I like the idea very much however. Quote
Toastie Posted August 27, 2010 Author Posted August 27, 2010 How would you use PID control on a LEGO train then?! It is kind of strange for a train to use PID, it is more suitable for robots isn't it?! Update: after seeing the nice video, I understand what you mean, but that is not PID, it is more like the servo principal. I like the idea very much however. Hi JopieK, this is a good question and comment! Well as far as I understand PID loops and servos (I may be quite wrong here!): The 9 V train motor alone is just that: A simple DC motor. Many people call a closed-loop system that does not use a stepper motor a servo system or "servo". So a simple DC motor that is connected to any kind of velocity controller may be called a servo motor. In this regard you are absolutely right: The combination rotation sensor + RCX + 9 V train motor (with both motor and sensor on the rails = closed loop) is representing a servo system. There are many different kinds of control loops; for servos quite often PID is implemented. So I guess you are right: The closed loop installed on my trains is representing a servo system. And this system uses the PID algorithm for control (so my statement may be right as well ...). I have programmed the PID algorithm into the RCX as one task. It just monitors the rotation sensor reading every 60 ms and then calculates the deviation form the set point (desired speed) and the other errors you need for PID to adjust the motor power output level. I hope that this makes sense. Regards, Thorsten How would you use PID control on a LEGO train then?! It is kind of strange for a train to use PID, it is more suitable for robots isn't it?! Update: after seeing the nice video, I understand what you mean, but that is not PID, it is more like the servo principal. I like the idea very much however. Hi JopieK, I forgot: This is the code for the PID loop running on the RCX. Just in case. The entire program can be donwloaded on the RailBricks website, section build instructions, diesels, gp40_RCX. Regards, Thorsten //--------------------------------------------------------------------------------------------------------------------- task PIDSpeedControl() { /* PID loop. The algorithm is adapted from the eBook "The PID Control Algorithm - How it works, how to tune it, and how to use it" by John A. Shaw (2nd edition, 2005). Some data on the LEGO RCX rotoation sensor used for train speed measurement: - 16 ticks per 360 deg rotation. - 5.5 cm travel path per 360 deg rotation using the RC trainwheels = 3.4 mm per tick. */ //Local constants const int cnSpeedCalFactor = 320; //Calibration factor for rotation sensor reading/time[T2] => //speed conversion [% scale]. //Local variables //Variables used in referenced BASIC code. //--------------------------------------------------//--------------------------------------------------------------- float fActualSpeed; //Input [%]. float fActualSpeedD; //InputD. float fActualSpeedLast = 0; //InputLast; needs to be initialized for first PID loop. float fPIDError; //Err. float fPIDFeedBack = 0; //Feedback; needs to be initialized for first PID loop. float fOutputPower; //OutP. //PID_ROT_SENSOR_DIR //Action. //bFlagPIDSpeedControl //Mode. //not required (?) //OutPutTemp. //nPIDSpeedSetpoint //SetP. ClearTimer(TMR_SPEED); //Reset speed measurement timer 2 for initial PID loop access. SensorValue[ROT_SENSOR_IN_1] = 0; //Reset any accumulated rotation sensor ticks on log. input 1 //for initial PID loop access. //--- PID loop ------------------------------------------------------------------------------------------------------ while (true) { while (time1[TMR_SPEED] < nPIDLoopWaitTime); //Note: 0 ms loop time delay is too short to accumulate //meaningful rotation sensor tick readings at low speeds. fActualSpeed = SensorValue[ROT_SENSOR_IN_1] * cnSpeedCalFactor * PID_ROT_SENSOR_DIR / time1[TMR_SPEED]; //Speed calculation. ClearTimer(TMR_SPEED); //Reset speed measurent timer. SensorValue[ROT_SENSOR_IN_1] = 0; //Reset accumulated rotation sensor data. if (bFlagPIDSpeedControl) //PID algorithm ------------------------------------------------------------------------- { fActualSpeedD = fActualSpeed + (fActualSpeed - fActualSpeedLast) * fPIDDerivTime; fActualSpeedLast = fActualSpeed; //Store current speed value. fPIDError = nPIDSpeedSetpoint - fActualSpeedD; //nPIDSpeedSetpoint is calculated from nRampedPower. fOutputPower = (fPIDError * fPIDGain) + fPIDFeedBack; if (fOutputPower > 100) fOutputPower = 100; //Restrict nOutputPower to firmware power range. if (fOutputPower < -100) fOutputPower = -100; fPIDFeedBack += (fOutputPower - fPIDFeedBack) * fPIDResetRate; if ((nRampedPower == 0) && (fActualSpeed == 0)){//Required to fully remove power from the motors; at low output fOutputPower = 0; //power levels the train stops with zero PID loop error but fPIDFeedBack = 0; //power is still around 20 with no torque and speed = 0. fActualSpeedLast = 0; } } else //Manual speed control --------------------------------------------------------------------------------------- { fOutputPower = nRampedPower; //Set output power to ramped power as calcualted in task //ramp_power [% scale]. fPIDFeedBack = fOutputPower; //Store PIDFeedback and current speed for bumpless transfer from fActualSpeedLast = fActualSpeed; //manual into PID mode. } motor[OUT_1] = fOutputPower * DIR_1; //Set motor power, recognize motor wiring direction. #if MOTORS == 2 //motor[] accepts floats (rounded >down< to integers). motor[OUT_2] = fOutputPower * DIR_2; #endif }//while (true) }//task PID_speed_control Quote
elicend Posted November 29, 2013 Posted November 29, 2013 hi i tryed to make a post for building a standard RCX train controller, and your way of work is very impressive. a second member has made train reading track information in order of making interactions, and i hope a mix should be created ;) can you help me ? Standard RCX Train controler Quote
Fugazi Posted December 1, 2013 Posted December 1, 2013 Elicend, again please do not bump old topics without good reason. If you need help, try reaching the original poster by PM (personal messenger). Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.