Added mechanical friction
This commit is contained in:
parent
16561c9d32
commit
87e3ff33ca
5 changed files with 43 additions and 45 deletions
|
@ -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
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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?
|
||||||
*
|
*
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue