Added mechanical friction

This commit is contained in:
Calclavia 2015-01-23 11:41:55 +08:00
parent 16561c9d32
commit 87e3ff33ca
5 changed files with 43 additions and 45 deletions

View file

@ -32,10 +32,15 @@ trait TNodeMechanical extends INode with IVectorWorld
* *
* A higher resistance or moment of inertia means that it is more difficult for this mechanical node to accelerate. * A higher resistance or moment of inertia means that it is more difficult for this mechanical node to accelerate.
* *
* @return Power loss in Watts. * @return Moment of intertia
*/ */
def inertia = 10D def inertia = 10D
/**
* Friction is a factor that decelerates the mechanical system based on angular velocity.
*/
def friction = 1D
/** /**
* The radius of rotation * The radius of rotation
*/ */

View file

@ -87,16 +87,6 @@ class TileMotor extends SpatialTile(Material.iron) with TIO with TElectric with
{ {
super.update() super.update()
/**
* Produce torque based on current.
* T = NBA * I / (2pi)
*/
val torque = TileMotor.motorConstant * electricNode.current / (2 * Math.PI)
//TODO: Check if angular velocity should be generated based on torque
if (torque != 0)
mechNode.accelerate(torque)
/** /**
* Motors produce emf or counter-emf by Lenz's law based on angular velocity * Motors produce emf or counter-emf by Lenz's law based on angular velocity
* emf = change of flux/time * emf = change of flux/time
@ -107,7 +97,15 @@ class TileMotor extends SpatialTile(Material.iron) with TIO with TElectric with
* where w = angular velocity * where w = angular velocity
*/ */
val inducedEmf = TileMotor.motorConstant * mechNode.angularVelocity // * Math.sin(mechNode.angularVelocity * System.currentTimeMillis() / 1000d) val inducedEmf = TileMotor.motorConstant * mechNode.angularVelocity // * Math.sin(mechNode.angularVelocity * System.currentTimeMillis() / 1000d)
electricNode.generateVoltage(inducedEmf * -1)
/**
* Produce torque based on current.
* T = NBA * I / (2pi)
*/
//TODO: Torque should be based on the current, as a result of counter-emf
val torque = TileMotor.motorConstant * ((electricNode.voltage - inducedEmf) / electricNode.resistance) / (2 * Math.PI)
mechNode.accelerate(torque)
// electricNode.generateVoltage(inducedEmf * -1)
} }
override def setIO(dir: ForgeDirection, ioType: Int) override def setIO(dir: ForgeDirection, ioType: Int)

View file

@ -22,11 +22,23 @@ class NodeGear(parent: PartGear) extends NodeMechanical(parent: PartGear)
override def inertia: Double = override def inertia: Double =
{ {
return gear.tier match gear.tier match
{ {
case 0 => 60 case 0 => 50
case 1 => 80 case 1 => 80
case 2 => 50 case 2 => 75
}
}
protected def gear = getParent.asInstanceOf[PartGear]
override def friction: Double =
{
gear.tier match
{
case 0 => 2
case 1 => 3
case 2 => 1
} }
} }
@ -102,8 +114,6 @@ class NodeGear(parent: PartGear) extends NodeMechanical(parent: PartGear)
} }
} }
protected def gear = getParent.asInstanceOf[PartGear]
/** /**
* Can this gear be connected BY the source? * Can this gear be connected BY the source?
* *

View file

@ -27,8 +27,6 @@ import resonant.lib.utility.WrenchUtility
class PartGear extends PartMechanical with IMultiBlockStructure[PartGear] class PartGear extends PartMechanical with IMultiBlockStructure[PartGear]
{ {
val multiBlock = new GearMultiBlockHandler(this) val multiBlock = new GearMultiBlockHandler(this)
var isClockwiseCrank = true
var manualCrankTime = 0
var multiBlockRadius = 1 var multiBlockRadius = 1
//Constructor //Constructor
@ -56,32 +54,16 @@ class PartGear extends PartMechanical with IMultiBlockStructure[PartGear]
override def update() override def update()
{ {
super.update() super.update()
if (!world.isRemote)
{
if (manualCrankTime > 0)
{
//A punch has around 5000 Newtons
mechanicalNode.accelerate((if (isClockwiseCrank) 2 else -2) * manualCrankTime)
manualCrankTime -= 1
}
}
getMultiBlock.update() getMultiBlock.update()
} }
override def activate(player: EntityPlayer, hit: MovingObjectPosition, itemStack: ItemStack): Boolean = override def activate(player: EntityPlayer, hit: MovingObjectPosition, itemStack: ItemStack): Boolean =
{ {
if (!world.isRemote)
println(mechanicalNode + " in " + mechanicalNode.grid)
if (itemStack != null && itemStack.getItem.isInstanceOf[ItemHandCrank]) if (itemStack != null && itemStack.getItem.isInstanceOf[ItemHandCrank])
{ {
isClockwiseCrank = player.isSneaking mechanicalNode.accelerate((if (player.isSneaking) 1 else -1) * 4000)
getMultiBlock.get.manualCrankTime = 40
world.playSoundEffect(x + 0.5, y + 0.5, z + 0.5, Reference.prefix + "gearCrank", 0.5f, 0.9f + world.rand.nextFloat * 0.2f) world.playSoundEffect(x + 0.5, y + 0.5, z + 0.5, Reference.prefix + "gearCrank", 0.5f, 0.9f + world.rand.nextFloat * 0.2f)
player.addExhaustion(0.01f) player.addExhaustion(0.02f)
return true return true
} }

View file

@ -19,7 +19,8 @@ class GridMechanical extends GridNode[NodeMechanical] with IUpdate
/** /**
* The nodes that the grid is currently recusing through * The nodes that the grid is currently recusing through
*/ */
private var allPassed = Seq.empty[NodeMechanical] private var allRecursed = Seq.empty[NodeMechanical]
private var allDistributed = Seq.empty[NodeMechanical]
nodeClass = classOf[NodeMechanical] nodeClass = classOf[NodeMechanical]
@ -50,7 +51,7 @@ class GridMechanical extends GridNode[NodeMechanical] with IUpdate
n => n =>
{ {
n.torque = 0 n.torque = 0
// n.angularVelocity = 0 n.angularVelocity -= n.angularVelocity * deltaTime * n.friction
} }
) )
@ -61,13 +62,13 @@ class GridMechanical extends GridNode[NodeMechanical] with IUpdate
getNodes.filter(n => n.bufferTorque != 0).foreach( getNodes.filter(n => n.bufferTorque != 0).foreach(
n => n =>
{ {
allPassed = Seq(n) allDistributed = Seq(n)
recurse(Seq(n), deltaTime, n.bufferTorque, 0) recurse(Seq(n), deltaTime, n.bufferTorque, 0)
} }
) )
} }
allPassed = Seq.empty[NodeMechanical] allDistributed = Seq.empty[NodeMechanical]
resetNodes() resetNodes()
} }
@ -98,12 +99,14 @@ class GridMechanical extends GridNode[NodeMechanical] with IUpdate
def calculateEquivalentInertia(passed: Seq[NodeMechanical]): Double = def calculateEquivalentInertia(passed: Seq[NodeMechanical]): Double =
{ {
val curr = passed.last val curr = passed.last
allRecursed :+= curr
/** /**
* I1 + n^2 * I * I1 + n^2 * I
* where n is the acceleration ratio * where n is the acceleration ratio
*/ */
var inertia = curr.inertia var inertia = curr.inertia
inertia += curr.connections.map(c => c.radius(curr) / curr.radius(c) * calculateEquivalentInertia(passed :+ c)).foldLeft(0d)(_ + _) inertia += curr.connections.filterNot(allRecursed.contains).map(c => c.radius(curr) / curr.radius(c) * calculateEquivalentInertia(passed :+ c)).foldLeft(0d)(_ + _)
return inertia return inertia
} }
@ -126,9 +129,9 @@ class GridMechanical extends GridNode[NodeMechanical] with IUpdate
{ {
if (c != prev) if (c != prev)
{ {
if (!allPassed.contains(c)) if (!allDistributed.contains(c))
{ {
allPassed :+= c allDistributed :+= c
recurse(passed :+ c, deltaTime, addTorque, addVel) recurse(passed :+ c, deltaTime, addTorque, addVel)
} }
else else
@ -162,7 +165,7 @@ class GridMechanical extends GridNode[NodeMechanical] with IUpdate
curr.angularVelocity += netAcceleration * deltaTime curr.angularVelocity += netAcceleration * deltaTime
curr.connections.foreach(c => curr.connections.foreach(c =>
{ {
allPassed :+= c allDistributed :+= c
recurse(passed :+ c, deltaTime, netTorque, netAcceleration) recurse(passed :+ c, deltaTime, netTorque, netAcceleration)
}) })
} }