Exemple #1
0
void Move::SetProbedBedEquation()
{
	float currentPositions[DRIVES+1];
	if(!GetCurrentState(currentPositions))
	{
		platform->Message(HOST_MESSAGE, "Setting bed equation - can't get position!");
		return;
	}

	if(NumberOfProbePoints() >= 3)
	{
		secondDegreeCompensation = (NumberOfProbePoints() == 4);
		if(secondDegreeCompensation)
		{
			/*
			 * Transform to a ruled-surface quadratic.  The corner points for interpolation are indexed:
			 *
			 *   ^  [1]      [2]
			 *   |
			 *   Y
			 *   |
			 *   |  [0]      [3]
			 *      -----X---->
			 *
			 *   These are the scaling factors to apply to x and y coordinates to get them into the
			 *   unit interval [0, 1].
			 */
			xRectangle = 1.0/(xBedProbePoints[3] - xBedProbePoints[0]);
			yRectangle = 1.0/(yBedProbePoints[1] - yBedProbePoints[0]);
			Transform(currentPositions);
			SetPositions(currentPositions);
			return;
		}
	} else
	{
		platform->Message(HOST_MESSAGE, "Attempt to set bed compensation before all probe points have been recorded.");
		return;
	}

	float xkj, ykj, zkj;
	float xlj, ylj, zlj;
	float a, b, c, d;   // Implicit plane equation - what we need to do a proper job

	xkj = xBedProbePoints[1] - xBedProbePoints[0];
	ykj = yBedProbePoints[1] - yBedProbePoints[0];
	zkj = zBedProbePoints[1] - zBedProbePoints[0];
	xlj = xBedProbePoints[2] - xBedProbePoints[0];
	ylj = yBedProbePoints[2] - yBedProbePoints[0];
	zlj = zBedProbePoints[2] - zBedProbePoints[0];
	a = ykj*zlj - zkj*ylj;
	b = zkj*xlj - xkj*zlj;
	c = xkj*ylj - ykj*xlj;
	d = -(xBedProbePoints[1]*a + yBedProbePoints[1]*b + zBedProbePoints[1]*c);
	aX = -a/c;
	aY = -b/c;
	aC = -d/c;
	Transform(currentPositions);
	SetPositions(currentPositions);
}
Exemple #2
0
void Move::SetAxisCompensation(int8_t axis, float tangent)
{
	float currentPositions[DRIVES+1];
	if(!GetCurrentState(currentPositions))
	{
		platform->Message(HOST_MESSAGE, "Setting bed equation - can't get position!");
		return;
	}

	switch(axis)
	{
	case X_AXIS:
		tanXY = tangent;
		break;
	case Y_AXIS:
		tanYZ = tangent;
		break;
	case Z_AXIS:
		tanXZ = tangent;
		break;
	default:
		platform->Message(HOST_MESSAGE, "SetAxisCompensation: dud axis.\n");
	}
	Transform(currentPositions);
	SetPositions(currentPositions);
}
Exemple #3
0
void WheelBase::Load( RString sType )
{
    LOG->Trace( "WheelBase::Load('%s')", sType.c_str() );
    ASSERT( this->GetNumChildren() == 0 ); // only load once

    m_bEmpty = false;
    m_LastSelection = NULL;
    m_iSelection = 0;
    m_fTimeLeftInState = 0;
    m_fPositionOffsetFromSelection = 0;
    m_iSwitchesLeftInSpinDown = 0;
    m_Moving = 0;

    SWITCH_SECONDS			.Load(sType,"SwitchSeconds");
    LOCKED_INITIAL_VELOCITY		.Load(sType,"LockedInitialVelocity");
    SCROLL_BAR_HEIGHT		.Load(sType,"ScrollBarHeight");
    m_exprItemTransformFunction.SetFromReference( THEME->GetMetricR(sType,"ItemTransformFunction") );
    NUM_WHEEL_ITEMS_TO_DRAW		.Load(sType,"NumWheelItems");
    WHEEL_ITEM_LOCKED_COLOR		.Load(sType,"WheelItemLockedColor");

    m_soundChangeMusic.Load(	THEME->GetPathS(sType,"change"), true );
    m_soundLocked.Load(		THEME->GetPathS(sType,"locked"), true );

    WheelItemBase *pTempl = MakeItem();
    ActorUtil::LoadAllCommands( *pTempl, m_sName );
    pTempl->PlayCommand( "Init" );
    for( int i=0; i<NUM_WHEEL_ITEMS; i++ )
    {
        WheelItemBase *pItem = pTempl->Copy();
        DEBUG_ASSERT( pItem );
        m_WheelBaseItems.push_back( pItem );
    }
    SAFE_DELETE( pTempl );

    // draw outside->inside
    for( int i=0; i<NUM_WHEEL_ITEMS/2; i++ )
        this->AddChild( m_WheelBaseItems[i] );
    for( int i=NUM_WHEEL_ITEMS-1; i>=NUM_WHEEL_ITEMS/2; i-- )
        this->AddChild( m_WheelBaseItems[i] );

    m_sprHighlight.Load( THEME->GetPathG(sType,"highlight") );
    m_sprHighlight->SetName( "Highlight" );
    this->AddChild( m_sprHighlight );
    ActorUtil::LoadAllCommands( *m_sprHighlight, m_sName );

    m_ScrollBar.SetName( "ScrollBar" );
    m_ScrollBar.SetBarHeight( SCROLL_BAR_HEIGHT );
    this->AddChild( &m_ScrollBar );
    ActorUtil::LoadAllCommands( m_ScrollBar, m_sName );

    SetPositions();
}
Exemple #4
0
void WheelBase::TweenOnScreenForSort()
{
    m_fPositionOffsetFromSelection = 0;

    /* Before we send SortOn, position items back to their destinations, so commands
     * can use this as a reference point. */
    SetPositions();

    m_WheelState = STATE_FLYING_ON_AFTER_NEXT_SORT;

    this->PlayCommand( "SortOn" );

    m_fTimeLeftInState = GetTweenTimeLeft();
}
Exemple #5
0
Grid::Grid(sf::Vector2f sizes, sf::RenderWindow& windowRef) : size{sizes}, winRef{windowRef} {

    boxes=NULL;
    
    pointSize = 9; // force  9 for the TicTacToe grid.

    sf::Vector2f reducedSizes(size.x / 3, size.y / 3);

    boxes = new sf::RectangleShape[pointSize];

    for (int i = 0; i < pointSize; i++) {
        boxes[i].setSize(reducedSizes);
        boxes[i].setFillColor(sf::Color::Transparent);
        boxes[i].setOutlineColor(sf::Color::Blue);
        boxes[i].setOutlineThickness(4);
        SetPositions(boxes[i], i);
    }
}
Exemple #6
0
//Sets play area border sizes
PlayArea::PlayArea()
{
	width = 800;
	height = 600;
	borderSize = 50;
	enemyBorderWidth = 1800;

	//(800, 50)
	topBorder = RectangleShape(Vector2f(width, borderSize));
	bottomBorder = RectangleShape(Vector2f(width, borderSize));

	//(50, 600)
	rightBorder = RectangleShape(Vector2f(borderSize, height));
	leftBorder = RectangleShape(Vector2f(borderSize, height));

	//(1800, 50)
	enemyBorder = RectangleShape(Vector2f(enemyBorderWidth, borderSize));

	SetPositions();
}
Exemple #7
0
STDMETHODIMP CStreamSwitcherPassThru::SetPositions(LONGLONG* pCurrent, DWORD CurrentFlags, LONGLONG* pStop, DWORD StopFlags)
{
    CallPeerSeekingAll(SetPositions(pCurrent, CurrentFlags, pStop, StopFlags));
}
void ChangeSize(USHORT usSize, BOOL fXYZT)
{
   SetPositions(usSize);
   SwitchFonts(usSize);
   SwitchSizes(fXYZT);
}
Exemple #9
0
void WheelBase::Update( float fDeltaTime )
{
    ActorFrame::Update( fDeltaTime );

    /* If tweens aren't controlling the position of the wheel, set positions. */
    if( !GetTweenTimeLeft() )
        SetPositions();

    for( int i=0; i<NUM_WHEEL_ITEMS; i++ )
    {
        WheelItemBase *pDisplay = m_WheelBaseItems[i];
        if( m_WheelState == STATE_LOCKED  &&  i != NUM_WHEEL_ITEMS/2 )
            pDisplay->m_colorLocked = WHEEL_ITEM_LOCKED_COLOR.GetValue();
        else
            pDisplay->m_colorLocked = RageColor(0,0,0,0);
    }

    //Moved to CommonUpdateProcedure, seems to work fine
    //Revert if it happens to break something
    UpdateScrollbar();

    if( m_Moving )
    {
        m_TimeBeforeMovingBegins -= fDeltaTime;
        m_TimeBeforeMovingBegins = max(m_TimeBeforeMovingBegins, 0);
    }

    // update wheel state
    m_fTimeLeftInState -= fDeltaTime;
    if( m_fTimeLeftInState <= 0 )	// time to go to a new state
        UpdateSwitch();

    if( m_WheelState == STATE_LOCKED )
    {
        /* Do this in at most .1 sec chunks, so we don't get weird if we
         * stop for some reason (and so it behaves the same when being
         * single stepped). */
        float fTime = fDeltaTime;
        while( fTime > 0 )
        {
            float t = min( fTime, 0.1f );
            fTime -= t;

            m_fPositionOffsetFromSelection = clamp( m_fPositionOffsetFromSelection, -0.3f, +0.3f );

            float fSpringForce = - m_fPositionOffsetFromSelection * LOCKED_INITIAL_VELOCITY;
            m_fLockedWheelVelocity += fSpringForce;

            float fDrag = -m_fLockedWheelVelocity * t*4;
            m_fLockedWheelVelocity += fDrag;

            m_fPositionOffsetFromSelection  += m_fLockedWheelVelocity*t;

            if( fabsf(m_fPositionOffsetFromSelection) < 0.01f  &&  fabsf(m_fLockedWheelVelocity) < 0.01f )
            {
                m_fPositionOffsetFromSelection = 0;
                m_fLockedWheelVelocity = 0;
            }
        }
    }

    if( IsMoving() )
    {
        /* We're automatically moving.  Move linearly, and don't clamp
         * to the selection. */
        float fSpinSpeed = m_SpinSpeed*m_Moving;
        m_fPositionOffsetFromSelection -= fSpinSpeed*fDeltaTime;

        /* Make sure that we don't go further than 1 away, in case the
         * speed is very high or we miss a lot of frames. */
        m_fPositionOffsetFromSelection  = clamp(m_fPositionOffsetFromSelection, -1.0f, 1.0f);

        /* If it passed the selection, move again. */
        if((m_Moving == -1 && m_fPositionOffsetFromSelection >= 0) ||
                (m_Moving == 1 && m_fPositionOffsetFromSelection <= 0))
        {
            ChangeMusic( m_Moving );

            if( PREFSMAN->m_iMusicWheelSwitchSpeed < MAX_WHEEL_SOUND_SPEED )
                m_soundChangeMusic.Play();
        }

        if( PREFSMAN->m_iMusicWheelSwitchSpeed >= MAX_WHEEL_SOUND_SPEED &&
                m_MovingSoundTimer.PeekDeltaTime() >= 1.0f / MAX_WHEEL_SOUND_SPEED )
        {
            m_MovingSoundTimer.GetDeltaTime();
            m_soundChangeMusic.Play();
        }
    }
    else
    {
        // "rotate" wheel toward selected song
        float fSpinSpeed = 0.2f + fabsf( m_fPositionOffsetFromSelection ) / SWITCH_SECONDS;

        if( m_fPositionOffsetFromSelection > 0 )
        {
            m_fPositionOffsetFromSelection -= fSpinSpeed*fDeltaTime;
            if( m_fPositionOffsetFromSelection < 0 )
                m_fPositionOffsetFromSelection = 0;
        }
        else if( m_fPositionOffsetFromSelection < 0 )
        {
            m_fPositionOffsetFromSelection += fSpinSpeed*fDeltaTime;
            if( m_fPositionOffsetFromSelection > 0 )
                m_fPositionOffsetFromSelection = 0;
        }
    }
}
Exemple #10
0
ButtonModel::ButtonModel(WiiHandler * wiiHandler, GameState * state, string filename):ObjModel(filename)
{
	this->wiiHandler = wiiHandler;
	this->state = state;
	SetPositions(0, 0, 0, 0, 0);
}
Exemple #11
0
bool GCodes::ActOnGcode(GCodeBuffer *gb)
{
  int code;
  float value;
  int iValue;
  char* str;
  bool result = true;
  bool error = false;
  bool resend = false;
  bool seen;
  char reply[STRING_LENGTH];

  reply[0] = 0;

  if(gb->Seen('G'))
  {
    code = gb->GetIValue();
    switch(code)
    {
    case 0: // There are no rapid moves...
    case 1: // Ordinary move
      result = SetUpMove(gb);
      break;
      
    case 4: // Dwell
      result = DoDwell(gb);
      break;
      
    case 10: // Set offsets
      result = SetOffsets(gb);
      break;
    
    case 20: // Inches (which century are we living in, here?)
      distanceScale = INCH_TO_MM;
      break;
    
    case 21: // mm
      distanceScale = 1.0;
      break;
    
    case 28: // Home
      if(NoHome())
      {
    	homeAxisMoveCount = 0;
        homeX = gb->Seen(gCodeLetters[X_AXIS]);
        homeY = gb->Seen(gCodeLetters[Y_AXIS]);
        homeZ = gb->Seen(gCodeLetters[Z_AXIS]);
        if(NoHome())
        {
          homeX = true;
          homeY = true;
          homeZ = true;
        }
      }
      result = DoHome();
      break;

    case 30: // Z probe/manually set at a position and set that as point P
    	result = SetSingleZProbeAtAPosition(gb);
    	break;

    case 31: // Return the probe value, or set probe variables
    	result = SetPrintZProbe(gb, reply);
    	break;

    case 32: // Probe Z at multiple positions and generate the bed transform
    	result = DoMultipleZProbe();
    	break;

    case 90: // Absolute coordinates
      drivesRelative = false;
      axesRelative = false;
      break;
      
    case 91: // Relative coordinates
      drivesRelative = true; // Non-axis movements (i.e. extruders)
      axesRelative = true;   // Axis movements (i.e. X, Y and Z)
      break;
      
    case 92: // Set position
      result = SetPositions(gb);
      break;
      
    default:
    	error = true;
    	snprintf(reply, STRING_LENGTH, "invalid G Code: %s", gb->Buffer());
    }
    if(result)
    	HandleReply(error, gb == serialGCode, reply, 'G', code, resend);
    return result;
  }
  
  if(gb->Seen('M'))
  {
    code = gb->GetIValue();
    switch(code)
    {
    case 0: // Stop
    case 1: // Sleep
      if(fileBeingPrinted != NULL)
      {
    	  fileToPrint = fileBeingPrinted;
    	  fileBeingPrinted = NULL;
      }
      if(!DisableDrives())
    	  return false;
      if(!StandbyHeaters())
    	  return false; // Should never happen
      break;
    
    case 18: // Motors off
      result = DisableDrives();
      break;
      
    case 20:  // Deprecated...
      if(platform->Emulating() == me || platform->Emulating() == reprapFirmware)
    	  snprintf(reply, STRING_LENGTH, "GCode files:\n%s", platform->GetMassStorage()->FileList(platform->GetGCodeDir(), gb == serialGCode));
      else
    	  snprintf(reply, STRING_LENGTH, "%s", platform->GetMassStorage()->FileList(platform->GetGCodeDir(), gb == serialGCode));
      break;

    case 21: // Initialise SD - ignore
    	break;

    case 23: // Set file to print
      QueueFileToPrint(gb->GetUnprecedentedString());
      if(platform->Emulating() == marlin)
    	  snprintf(reply, STRING_LENGTH, "%s", "File opened\nFile selected\n");
      break;
      
    case 24: // Print/resume-printing the selected file
      if(fileBeingPrinted != NULL)
    	  break;
      fileBeingPrinted = fileToPrint;
      fileToPrint = NULL;
      break;
      
    case 25: // Pause the print
    	fileToPrint = fileBeingPrinted;
    	fileBeingPrinted = NULL;
    	break;

    case 27: // Report print status - Depricated
    	if(this->PrintingAFile())
    		strncpy(reply, "SD printing.", STRING_LENGTH);
    	else
    		strncpy(reply, "Not SD printing.", STRING_LENGTH);
    	break;

    case 28: // Write to file
    	str = gb->GetUnprecedentedString();
    	OpenFileToWrite(platform->GetGCodeDir(), str, gb);
    	snprintf(reply, STRING_LENGTH, "Writing to file: %s", str);
    	break;

    case 29: // End of file being written; should be intercepted before getting here
    	platform->Message(HOST_MESSAGE, "GCode end-of-file being interpreted.\n");
    	break;

    case 82:
    	for(int8_t extruder = AXES; extruder < DRIVES; extruder++)
    		lastPos[extruder - AXES] = 0.0;
    	drivesRelative = false;
    	break;

    case 83:
    	for(int8_t extruder = AXES; extruder < DRIVES; extruder++)
    		lastPos[extruder - AXES] = 0.0;
    	drivesRelative = true;

    	break;

    case 84: // Motors off - deprecated, use M18
        result = DisableDrives();
        break;

    case 85: // Set inactive time
    	break;

    case 92: // Set/report steps/mm for some axes
    	seen = false;
    	for(int8_t drive = 0; drive < DRIVES; drive++)
    		if(gb->Seen(gCodeLetters[drive]))
    		{
    			platform->SetDriveStepsPerUnit(drive, gb->GetFValue());
    			seen = true;
    		}
    	reprap.GetMove()->SetStepHypotenuse();
    	if(!seen)
    		snprintf(reply, STRING_LENGTH, "Steps/mm: X: %d, Y: %d, Z: %d, E: %d",
    				(int)platform->DriveStepsPerUnit(X_AXIS), (int)platform->DriveStepsPerUnit(Y_AXIS),
    				(int)platform->DriveStepsPerUnit(Z_AXIS), (int)platform->DriveStepsPerUnit(AXES)); // FIXME - needs to do multiple extruders
        break;


    case 98:
    	if(gb->Seen('P'))
    		result = DoFileCannedCycles(gb->GetString());
    	break;

    case 99:
    	result = FileCannedCyclesReturn();
    	break;

    case 104: // Depricated
    	if(gb->Seen('S'))
    	{
    		reprap.GetHeat()->SetActiveTemperature(1, gb->GetFValue()); // 0 is the bed
    		reprap.GetHeat()->Activate(1);
    	}
    	break;

    case 105: // Deprecated...
    	strncpy(reply, "T:", STRING_LENGTH);
    	for(int8_t heater = HEATERS - 1; heater > 0; heater--)
    	{
    		strncat(reply, ftoa(0, reprap.GetHeat()->GetTemperature(heater), 1), STRING_LENGTH);
    		strncat(reply, " ", STRING_LENGTH);
    	}
    	strncat(reply, "B:", STRING_LENGTH);
    	strncat(reply, ftoa(0, reprap.GetHeat()->GetTemperature(0), 1), STRING_LENGTH);
    	break;
   
    case 106: // Fan on or off
    	if(gb->Seen('S'))
    		platform->CoolingFan(gb->GetFValue());
      break;
    
    case 107: // Fan off - depricated
    	platform->CoolingFan(0.0);
      break;
      
    case 110: // Set line numbers - line numbers are dealt with in the GCodeBuffer class, so ignore
    	break;

    case 111: // Debug level
    	if(gb->Seen('S'))
    		reprap.SetDebug(gb->GetIValue());
    	break;

    case 112: // Emergency stop - acted upon in Webserver
    	break;

    case 114: // Deprecated
    	str = GetCurrentCoordinates();
    	if(str != 0)
    	{
    		strncpy(reply, str, STRING_LENGTH);
    	} else
    		result = false;
    	break;

    case 115: // Print firmware version
    	snprintf(reply, STRING_LENGTH, "FIRMWARE_NAME:%s FIRMWARE_VERSION:%s ELECTRONICS:%s DATE:%s", NAME, VERSION, ELECTRONICS, DATE);
    	break;

    case 109: // Depricated
    	if(gb->Seen('S'))
    	{
    		reprap.GetHeat()->SetActiveTemperature(1, gb->GetFValue()); // 0 is the bed
    		reprap.GetHeat()->Activate(1);
    	}
    case 116: // Wait for everything, especially set temperatures
    	if(!AllMovesAreFinishedAndMoveBufferIsLoaded())
    		return false;
    	result = reprap.GetHeat()->AllHeatersAtSetTemperatures();
    	break;

    case 120:
    	result = Push();
    	break;

    case 121:
      result = Pop();
      break;
    
    case 122:
      reprap.Diagnostics();
      break;
      
    case 126: // Valve open
      platform->Message(HOST_MESSAGE, "M126 - valves not yet implemented\n");
      break;
      
    case 127: // Valve closed
      platform->Message(HOST_MESSAGE, "M127 - valves not yet implemented\n");
      break;
      
    case 135: // Set PID sample interval
    	break;

    case 140: // Set bed temperature
      if(gb->Seen('S'))
      {
        reprap.GetHeat()->SetActiveTemperature(0, gb->GetFValue());
        reprap.GetHeat()->Activate(0);
      }
      break;
    
    case 141: // Chamber temperature
      platform->Message(HOST_MESSAGE, "M141 - heated chamber not yet implemented\n");
      break;

    case 201: // Set axis accelerations
    	for(int8_t drive = 0; drive < DRIVES; drive++)
    	{
    		if(gb->Seen(gCodeLetters[drive]))
    		{
    			value = gb->GetFValue();
    		}else{
    			value = -1;
    		}
    		platform->SetAcceleration(drive, value);
    	}
    	break;

    case 203: // Set maximum feedrates
    	for(int8_t drive = 0; drive < DRIVES; drive++)
    	{
    		if(gb->Seen(gCodeLetters[drive]))
    		{
    			value = gb->GetFValue()*distanceScale*0.016666667; // G Code feedrates are in mm/minute; we need mm/sec;
    			platform->SetMaxFeedrate(drive, value);
    		}
    	}
    	break;

    case 205:  //M205 advanced settings:  minimum travel speed S=while printing T=travel only,  B=minimum segment time X= maximum xy jerk, Z=maximum Z jerk
    	break;

    case 206:  // Offset axes
    	result = OffsetAxes(gb);
    	break;

    case 208: // Set maximum axis lengths
    	for(int8_t axis = 0; axis < AXES; axis++)
    	{
    		if(gb->Seen(gCodeLetters[axis]))
    		{
    			value = gb->GetFValue()*distanceScale;
    			platform->SetAxisLength(axis, value);
    		}
    	}
    	break;

    case 210: // Set homing feedrates
    	for(int8_t axis = 0; axis < AXES; axis++)
    	{
    		if(gb->Seen(gCodeLetters[axis]))
    		{
    			value = gb->GetFValue()*distanceScale*0.016666667;
    			platform->SetHomeFeedRate(axis, value);
    		}
    	}
    	break;

    case 301: // Set PID values
    	break;

    case 302: // Allow cold extrudes
    	break;

    case 304: // Set thermistor parameters
    	break;

    case 503: // list variable settings
    	result = SendConfigToLine();
    	break;

    case 550: // Set machine name
        	if(gb->Seen('P'))
        		reprap.GetWebserver()->SetName(gb->GetString());
        	break;

    case 551: // Set password
    	if(gb->Seen('P'))
    		reprap.GetWebserver()->SetPassword(gb->GetString());
    	break;

    case 552: // Set/Get IP address
    	if(gb->Seen('P'))
    		SetEthernetAddress(gb, code);
    	else
    	{
    		byte *ip = platform->IPAddress();
    		snprintf(reply, STRING_LENGTH, "IP address: %d.%d.%d.%d\n ", ip[0], ip[1], ip[2], ip[3]);
    	}
    	break;

    case 553: // Set/Get netmask
    	if(gb->Seen('P'))
    		SetEthernetAddress(gb, code);
    	else
    	{
    		byte *nm = platform->NetMask();
    		snprintf(reply, STRING_LENGTH, "Net mask: %d.%d.%d.%d\n ", nm[0], nm[1], nm[2], nm[3]);
    	}
    	break;

    case 554: // Set/Get gateway
    	if(gb->Seen('P'))
    		SetEthernetAddress(gb, code);
    	else
    	{
    		byte *gw = platform->GateWay();
    		snprintf(reply, STRING_LENGTH, "Gateway: %d.%d.%d.%d\n ", gw[0], gw[1], gw[2], gw[3]);
    	}
    	break;

    case 555: // Set firmware type to emulate
    	if(gb->Seen('P'))
    		platform->SetEmulating((Compatibility)gb->GetIValue());
    	break;

    case 556: // Axis compensation
    	if(gb->Seen('S'))
    	{
    		value = gb->GetFValue();
    		for(int8_t axis = 0; axis < AXES; axis++)
    			if(gb->Seen(gCodeLetters[axis]))
    				reprap.GetMove()->SetAxisCompensation(axis, gb->GetFValue()/value);
    	}
    	break;

    case 557: // Set Z probe point coordinates
    	if(gb->Seen('P'))
    	{
    		iValue = gb->GetIValue();
    		if(gb->Seen(gCodeLetters[X_AXIS]))
    			reprap.GetMove()->SetXBedProbePoint(iValue, gb->GetFValue());
    		if(gb->Seen(gCodeLetters[Y_AXIS]))
    		    reprap.GetMove()->SetYBedProbePoint(iValue, gb->GetFValue());
    	}
    	break;

    case 558: // Set Z probe type
    	if(gb->Seen('P'))
    		platform->SetZProbeType(gb->GetIValue());
    	break;

    case 559: // Upload config.g
    	if(gb->Seen('P'))
    		str = gb->GetString();
    	else
    		str = platform->GetConfigFile();
        OpenFileToWrite(platform->GetSysDir(), str, gb);
        snprintf(reply, STRING_LENGTH, "Writing to file: %s", str);
    	break;

    case 560: // Upload reprap.htm
         str = INDEX_PAGE;
         OpenFileToWrite(platform->GetWebDir(), str, gb);
         snprintf(reply, STRING_LENGTH, "Writing to file: %s", str);
     	break;

    case 561:
    	reprap.GetMove()->SetIdentityTransform();
    	break;

    case 562: // Reset temperature fault - use with great caution
    	if(gb->Seen('P'))
    	{
    	    iValue = gb->GetIValue();
    	    reprap.GetHeat()->ResetFault(iValue);
    	}
    	break;

    case 876: // TEMPORARY - this will go away...
    	if(gb->Seen('P'))
    	{
    		iValue = gb->GetIValue();
    		if(iValue != 1)
    			platform->SetHeatOn(0);
    		else
    			platform->SetHeatOn(1);
    	}
    	break;

    case 900:
    	result = DoFileCannedCycles("homex.g");
    	break;

    case 901:
    	result = DoFileCannedCycles("homey.g");
    	break;



    case 906: // Set Motor currents
    	for(uint8_t i = 0; i < DRIVES; i++)
    	{
    		if(gb->Seen(gCodeLetters[i]))
    		{
    			value = gb->GetFValue(); // mA
    			platform->SetMotorCurrent(i, value);
    		}
    	}
    	break;

    case 998:
    	if(gb->Seen('P'))
    	{
    	    snprintf(reply, STRING_LENGTH, "%s", gb->GetIValue());
    	    resend = true;
    	}
    	break;
     
    default:
      error = true;
      snprintf(reply, STRING_LENGTH, "invalid M Code: %s", gb->Buffer());
    }
    if(result)
    	HandleReply(error, gb == serialGCode, reply, 'M', code, resend);
    return result;
  }
  
  if(gb->Seen('T'))
  {
    code = gb->GetIValue();
    if(code == selectedHead)
    {
    	if(result)
    		HandleReply(error, gb == serialGCode, reply, 'T', code, resend);
    	return result;
    }

    error = true;
    for(int8_t i = AXES; i < DRIVES; i++)
    {
    	if(selectedHead == i - AXES)
    		reprap.GetHeat()->Standby(selectedHead + 1); // + 1 because 0 is the Bed
    }
    for(int8_t i = AXES; i < DRIVES; i++)
    {    
      if(code == i - AXES)
      {
        selectedHead = code;
        reprap.GetHeat()->Activate(selectedHead + 1); // 0 is the Bed
        error = false;
      }
    }

    if(error)
      snprintf(reply, STRING_LENGTH, "Invalid T Code: %s", gb->Buffer());

    if(result)
    	HandleReply(error, gb == serialGCode, reply, 'T', code, resend);
    return result;
  }
  
  // An empty buffer jumps to here and gets discarded

  if(result)
  	HandleReply(error, gb == serialGCode, reply, 'X', code, resend);

  return result;
}