View
@@ -10,6 +10,10 @@
#include "Commands/Command.h"
#include "ErrorBase.h"
#include "SmartDashboard/NamedSendable.h"
+#include "networktables/NetworkTable.h"
+#include "networktables2/type/NumberArray.h"
+#include "networktables2/type/StringArray.h"
+#include "SmartDashboard/SmartDashboard.h"
#include <list>
#include <map>
#include <set>
@@ -18,7 +22,7 @@
class ButtonScheduler;
class Subsystem;
-class Scheduler : public ErrorBase
+class Scheduler : public ErrorBase, public NamedSendable
{
public:
static Scheduler *GetInstance();
@@ -30,6 +34,13 @@ class Scheduler : public ErrorBase
void Remove(Command *command);
void RemoveAll();
void SetEnabled(bool enabled);
+
+ void UpdateTable();
+ std::string GetSmartDashboardType();
+ void InitTable(ITable *subTable);
+ ITable * GetTable();
+ std::string GetName();
+ std::string GetType();
private:
Scheduler();
@@ -49,6 +60,11 @@ class Scheduler : public ErrorBase
CommandSet m_commands;
bool m_adding;
bool m_enabled;
+ StringArray *commands;
+ NumberArray *ids;
+ NumberArray *toCancel;
+ ITable *m_table;
+ bool m_runningCommandsChanged;
};
#endif
View
@@ -22,6 +22,7 @@ Subsystem::Subsystem(const char *name) :
m_name = name;
Scheduler::GetInstance()->RegisterSubsystem(this);
m_table = NULL;
+ m_currentCommandChanged = true;
}
/**
* Initialize the default command for this subsystem
@@ -106,6 +107,7 @@ Command *Subsystem::GetDefaultCommand()
void Subsystem::SetCurrentCommand(Command *command)
{
m_currentCommand = command;
+ m_currentCommandChanged = true;
}
/**
@@ -124,17 +126,20 @@ Command *Subsystem::GetCurrentCommand()
*/
void Subsystem::ConfirmCommand()
{
- if (m_table != NULL)
- {
- if (m_currentCommand != NULL)
- {
- m_table->PutBoolean("hasCommand", true);
- m_table->PutString("command", m_currentCommand->GetName());
- }
- else
+ if (m_currentCommandChanged) {
+ if (m_table != NULL)
{
- m_table->PutBoolean("hasCommand", false);
+ if (m_currentCommand != NULL)
+ {
+ m_table->PutBoolean("hasCommand", true);
+ m_table->PutString("command", m_currentCommand->GetName());
+ }
+ else
+ {
+ m_table->PutBoolean("hasCommand", false);
+ }
}
+ m_currentCommandChanged = false;
}
}
View
@@ -31,6 +31,7 @@ class Subsystem : public ErrorBase, public NamedSendable
void ConfirmCommand();
Command *m_currentCommand;
+ bool m_currentCommandChanged;
Command *m_defaultCommand;
std::string m_name;
bool m_initializedDefaultCommand;
View
@@ -306,9 +306,9 @@ HiTechnicColorSensor::RGB HiTechnicColorSensor::GetRawRGB()
m_i2c->Read(kRedRegister, sizeof(colors), (UINT8*)&colors);
}
- result.red = colors[0]<<8 + colors[1];
- result.green = colors[2]<<8 + colors[3];
- result.blue = colors[4]<<8 + colors[5];
+ result.red = (colors[0]<<8) + colors[1];
+ result.green = (colors[2]<<8) + colors[3];
+ result.blue = (colors[4]<<8) + colors[5];
return result;
}
View
@@ -63,7 +63,7 @@ void PIDController::Initialize(float Kp, float Ki, float Kd, float Kf,
{
m_table = NULL;
- m_semaphore = semBCreate(SEM_Q_PRIORITY, SEM_FULL);
+ m_semaphore = semMCreate(SEM_Q_PRIORITY);
m_controlLoop = new Notifier(PIDController::CallCalculate, this);
@@ -419,7 +419,7 @@ float PIDController::GetError()
float error;
CRITICAL_REGION(m_semaphore)
{
- error = GetSetpoint() - m_pidInput->PIDGet();
+ error = m_setpoint - m_pidInput->PIDGet();
}
END_REGION;
return error;
View
@@ -11,6 +11,7 @@
#include "WPIErrors.h"
#include <stdio.h>
+#include <algorithm>
/** Private NI function needed to write to the VxWorks target */
extern "C" int Priv_SetWriteFileAllowed(UINT32 enable);
@@ -592,16 +593,18 @@ void Preferences::ValueChanged(ITable* table, const std::string& key, EntryValue
if (!isKeyAcceptable(key) || table->GetString(key, "").find('"')!=std::string::npos)
{
- table->PutString(key, "\"");
- m_values.erase(key);
- std::vector<std::string>::iterator it = m_keys.begin();
- for (; it != m_keys.end(); it++)
- {
- if (key==*it)
+ if(m_values.find(key) != m_values.end()){
+ m_values.erase(key);
+ std::vector<std::string>::iterator it = m_keys.begin();
+ for (; it != m_keys.end(); it++)
{
- m_keys.erase(it);
- break;
+ if (key==*it)
+ {
+ m_keys.erase(it);
+ break;
+ }
}
+ table->PutString(key, "\"");
}
}
else
View
@@ -97,9 +97,9 @@ void WriteManager::run() {
{
Synchronized sync(entryStore.LOCK);
entry->MakeClean();
+ wrote = true;
+ receiver.offerOutgoingAssignment(entry);
}
- wrote = true;
- receiver.offerOutgoingAssignment(entry);
}
while(!((std::queue<NetworkTableEntry*>*)outgoingUpdateQueue)->empty()){
@@ -108,9 +108,9 @@ void WriteManager::run() {
{
Synchronized sync(entryStore.LOCK);
entry->MakeClean();
+ wrote = true;
+ receiver.offerOutgoingUpdate(entry);
}
- wrote = true;
- receiver.offerOutgoingUpdate(entry);
}
View
@@ -21,6 +21,7 @@
#include <sys/un.h>
#include <netdb.h>
#include <netinet/in.h>
+ #include <netinet/tcp.h>
#endif
#endif
#include "networktables2/stream/FDIOStream.h"
View
@@ -15,25 +15,69 @@ class ArrayData;
#include "networktables2/NetworkTableEntry.h"
/**
- *
- * @author Mitchell
+ * Defines the internal representation for an array.
*/
class ArrayData : public ComplexData{
private:
ArrayEntryType& m_data_type;
unsigned int m_size;
EntryValue* data;
public:
+ /**
+ * Creates a new ArrayData of the given type.
+ *
+ * @param type The ArrayEntryType representing the type
+ * information that this ArrayData should satisfy.
+ */
ArrayData(ArrayEntryType& type);
protected:
+ /**
+ * Gets the value stored at the specified index.
+ *
+ * @param index The array index to retrieve.
+ */
EntryValue _get(unsigned int index);
+
+ /**
+ * Updates the value stored at the specified index.
+ *
+ * The value currently stored at the given index is deleted.
+ *
+ * @param index The array index to update.
+ * @param value The value to store. This value must have
+ * the same type as the ArrayEntryType indicates.
+ */
void _set(unsigned int index, EntryValue value);
+
+ /**
+ * Appends the given value to the end of this array.
+ *
+ * @param value The value to store. This value must have
+ * the same type as the ArrayEntryType indicates.
+ */
void _add(EntryValue value);
public:
+ /**
+ * Removes and deletes the value stored at the specified index.
+ *
+ * @param index The index of the value to remove.
+ */
void remove(unsigned int index);
+
+ /**
+ * Sets the new size of this array data structure.
+ *
+ * @param size The new size that this array should assume.
+ */
void setSize(unsigned int size);
+
+ /**
+ * Gets the current size of this array data structure.
+ *
+ * @return The current number of elements that this array may contain.
+ */
unsigned int size();
friend class ArrayEntryType;
View
@@ -74,6 +74,7 @@ void ArrayEntryType::deleteValue(EntryValue value){
}
EntryValue ArrayEntryType::internalizeValue(std::string& key, ComplexData& externalRepresentation, EntryValue currentInteralValue) {
+ // TODO: Argument 'key' appears unused.
ArrayData& externalArrayData = (ArrayData&)externalRepresentation;
ArrayEntryData* internalArray = (ArrayEntryData*) currentInteralValue.ptr;
if(internalArray != NULL && internalArray->length==externalArrayData.size()){
View
@@ -23,31 +23,77 @@ struct ArrayEntryData{
uint8_t length;
EntryValue* array;
};
+/**
+ * Represents the size and contents of an array.
+ */
typedef struct ArrayEntryData ArrayEntryData;
/**
- *
- * @author Mitchell
+ * Represents the type of an array entry value.
*/
class ArrayEntryType : public ComplexEntryType {//TODO allow for array of complex type
private:
NetworkTableEntryType& m_elementType;
public:
+ /**
+ * Creates a new ArrayEntryType.
+ *
+ * @param id The ID which identifies this type to other nodes on
+ * across the network.
+ * @param elementType The type of the elements this array contains.
+ */
ArrayEntryType(TypeId id, NetworkTableEntryType& elementType);
+ /**
+ * Creates a copy of an value which is of the type contained by
+ * this array.
+ *
+ * @param value The element, of this array's contained type, to
+ * copy.
+ * @return A copy of the given value.
+ */
EntryValue copyElement(EntryValue value);
+
+ /**
+ * Deletes a entry value which is of the type contained by
+ * this array.
+ *
+ * After calling this method, the given entry value is
+ * no longer valid.
+ *
+ * @param value The value to delete.
+ */
void deleteElement(EntryValue value);
-
+
+ /**
+ * See {@link NetworkTableEntryType}::sendValue
+ */
void sendValue(EntryValue value, DataIOStream& os);
+ /**
+ * See {@link NetworkTableEntryType}::readValue
+ */
EntryValue readValue(DataIOStream& is);
-
+
+ /**
+ * See {@link NetworkTableEntryType}::copyValue
+ */
EntryValue copyValue(EntryValue value);
+
+ /**
+ * See {@link NetworkTableEntryType}::deleteValue
+ */
void deleteValue(EntryValue value);
-
+
+ /**
+ * See {@link ComplexEntryType}::internalizeValue
+ */
EntryValue internalizeValue(std::string& key, ComplexData& externalRepresentation, EntryValue currentInteralValue);
+ /**
+ * See {@link ComplexEntryType}::exportValue
+ */
void exportValue(std::string& key, EntryValue internalData, ComplexData& externalRepresentation);
View
@@ -11,10 +11,7 @@
#include "networktables2/type/ArrayData.h"
#include "networktables2/type/ArrayEntryType.h"
-/**
- *
- * @author Mitchell
- */
+//TODO: BooleanArray appears unused; replace with namespace?
class BooleanArray : public ArrayData{
public:
@@ -23,7 +20,7 @@ class BooleanArray : public ArrayData{
BooleanArray();
-
+
bool get(int index);
void set(int index, bool value);
void add(bool value);
View
@@ -15,17 +15,25 @@ class ComplexData;
//#include "ComplexEntryType.h" can't do this cause it causes order of definition issues
class ComplexEntryType;
-
+/**
+ * Base class for non-primitive data structures.
+ */
class ComplexData{
- /**
- *
- * @author Mitchell
- */
private:
ComplexEntryType& type;
public:
+ /**
+ * Creates a new ComplexData of the given type.
+ *
+ * @param type The type of this data structure.
+ */
ComplexData(ComplexEntryType& type);
+ /**
+ * Gets the type of this data structure.
+ *
+ * @return The type of this data structure.
+ */
ComplexEntryType& GetType();
};
View
@@ -12,6 +12,10 @@ class ComplexEntryType;
#include "networktables2/type/NetworkTableEntryType.h"
+/**
+ * Represents a non-primitive data type (i.e. not a string, double,
+ * or boolean).
+ */
class ComplexEntryType : public NetworkTableEntryType
{
protected:
@@ -20,8 +24,30 @@ class ComplexEntryType : public NetworkTableEntryType
virtual ~ComplexEntryType()
{
}
+
+ /**
+ * See {@link NetworkTableEntryType}::isComplex.
+ */
virtual bool isComplex();
+
+ /**
+ * Updates the internal representation for an entry of this type with the
+ * given value.
+ *
+ * @param key The name of the field to update.
+ * @param externalRepresentation The existing data structure to update.
+ * @param currentInternalValue The value to update the external representation with.
+ */
virtual EntryValue internalizeValue(std::string& key, ComplexData& externalRepresentation, EntryValue currentInteralValue) = 0;
+
+ /**
+ * Updates the given external representation for an entry of this type with
+ * the given internal value.
+ *
+ * @param key The name of the field to export.
+ * @param internalData The current value to reference.
+ * @param externalRepresentation The external representation to update.
+ */
virtual void exportValue(std::string& key, EntryValue internalData, ComplexData& externalRepresentation) = 0;
};
View
@@ -26,7 +26,14 @@ class DefaultEntryTypes{
class BOOLEAN_t : public NetworkTableEntryType{
public:
BOOLEAN_t();
+ /**
+ * See {@link NetworkTableEntryType}::sendValue
+ */
virtual void sendValue(EntryValue value, DataIOStream& os);
+
+ /**
+ * See {@link NetworkTableEntryType}::readValue
+ */
virtual EntryValue readValue(DataIOStream& is);
};
/**
@@ -35,7 +42,15 @@ class DefaultEntryTypes{
class DOUBLE_t : public NetworkTableEntryType{
public:
DOUBLE_t();
+
+ /**
+ * See {@link NetworkTableEntryType}::sendValue
+ */
virtual void sendValue(EntryValue value, DataIOStream& os);
+
+ /**
+ * See {@link NetworkTableEntryType}::sendValue
+ */
virtual EntryValue readValue(DataIOStream& is);
};
/**
@@ -44,13 +59,36 @@ class DefaultEntryTypes{
class STRING_t : public NetworkTableEntryType{
public:
STRING_t();
+
+ /**
+ * See {@link NetworkTableEntryType}::sendValue
+ */
virtual void sendValue(EntryValue value, DataIOStream& os);
+
+ /**
+ * See {@link NetworkTableEntryType}::sendValue
+ */
virtual EntryValue readValue(DataIOStream& is);
+
+ /**
+ * See {@link NetworkTableEntryType}::copyValue
+ */
virtual EntryValue copyValue(EntryValue value);
+
+ /**
+ * See {@link NetworkTableEntryType}::deleteValue
+ */
virtual void deleteValue(EntryValue value);
};
public:
+ /**
+ * Registers the set of default entry types with the given
+ * entry type manager.
+ *
+ * @param typeManager The entry type manager to update. Pointer must not be null.
+ */
static void registerTypes(NetworkTableEntryTypeManager* typeManager);
+
static BOOLEAN_t BOOLEAN;
static DOUBLE_t DOUBLE;
static STRING_t STRING;
View
@@ -14,6 +14,9 @@
#include <stdint.h>
#endif
+/**
+ * An ID which identifies a type to other nodes on the network.
+ */
typedef uint8_t TypeId;
class NetworkTableEntryType;
@@ -24,18 +27,65 @@ class NetworkTableEntryType;
#include "networktables2/NetworkTableEntry.h"
#include "tables/ITable.h"
-
+/**
+ * Represents the type associated with a network tables value.
+ */
class NetworkTableEntryType{
public:
const TypeId id;
const char* name;
+
+ /**
+ * Determines whether this data type is complex (i.e. it does not
+ * represent a number, string, or boolean).
+ *
+ * @return True of this type is complex. False otherwise.
+ */
virtual bool isComplex();
+
+ /**
+ * Serializes the given value on the given output stream.
+ *
+ * @param value The value to serialize.
+ * @param os The output stream to use.
+ */
virtual void sendValue(EntryValue value, DataIOStream& os) = 0;
+
+ /**
+ * Unserializes the a value of this type from the given
+ * input stream.
+ *
+ * @param is The input stream to read from.
+ * @return The unserialized value.
+ */
virtual EntryValue readValue(DataIOStream& is) = 0;
+
+ /**
+ * Creates a copy of the given value of this type.
+ *
+ * @param value The value to copy.
+ * @return A copy of the given value of this type.
+ */
virtual EntryValue copyValue(EntryValue value);
+
+ /**
+ * Deletes a value of this type.
+ *
+ * After calling this function, the given value is
+ * no longer valid.
+ *
+ * @param value The value to delete.
+ */
virtual void deleteValue(EntryValue value);
virtual ~NetworkTableEntryType();
protected:
+ /**
+ * Creates a new NetworkTablesEntryType.
+ *
+ * @param id The numeric ID associated with this type. This ID
+ * represents this data type to other nodes on the network.
+ * @param name The string name associated with this type.
+ */
NetworkTableEntryType(TypeId id, const char* name);
};
View
@@ -17,8 +17,30 @@ class NetworkTableEntryTypeManager
private:
NetworkTableEntryType* entryTypes[MAX_NUM_TABLE_ENTRY_TYPES];
public:
+ /**
+ * Creates a new NetworkTableEntryTypeManager, with the default
+ * types registered under their respective TypeID's, and all other
+ * TypeID's null.
+ */
NetworkTableEntryTypeManager();
+
+ /**
+ * Retrieves the entry type associated with the given
+ * type id, if one exists.
+ *
+ * @param type The identifier by which to retrieve a type.
+ * @return The NetworkTableEntryType associated with the given
+ * type identifier, if one exists. Otherwise, null.
+ */
NetworkTableEntryType* GetType(TypeId type);
+
+ /**
+ * Registers the given NetworkTableEntryType with this type
+ * manager, such that is is returned by subsequent calls
+ * to GetType with the appropriate ID.
+ *
+ * @param type The type to register.
+ */
void RegisterType(NetworkTableEntryType& type);
};
View
@@ -16,7 +16,7 @@ NumberArray::NumberArray() : ArrayData(TYPE) {
}
double NumberArray::get(int index){
- return _get(index).b;
+ return _get(index).f;
}
void NumberArray::set(int index, double value){
View
@@ -11,10 +11,7 @@
#include "networktables2/type/ArrayData.h"
#include "networktables2/type/ArrayEntryType.h"
-/**
- *
- * @author Mitchell
- */
+//TODO: NumberArray appears unused; replace with namespace?
class NumberArray : public ArrayData{
public:
View
@@ -12,10 +12,7 @@
#include "networktables2/type/ArrayData.h"
#include "networktables2/type/ArrayEntryType.h"
-/**
- *
- * @author Mitchell
- */
+//TODO: StringArray appears unused; replace with namespace?
class StringArray : public ArrayData{
public:
View
@@ -8,16 +8,24 @@
#ifndef EOFEXCEPTION_H_
#define EOFEXCEPTION_H_
-class EOFException;
-
#include "IOException.h"
-
+/**
+ * Indicates that an EOF was encountered during an I/O operation,
+ * and therefore the operation could not be completed.
+ */
class EOFException : public IOException{
public:
+ /**
+ * Creates an EOFException.
+ */
EOFException();
virtual ~EOFException() throw ();
+
+ /**
+ * Implements {@link IOException}::isEOF()
+ */
virtual bool isEOF();
};
View
@@ -8,20 +8,43 @@
#ifndef IOEXCEPTION_H_
#define IOEXCEPTION_H_
-
-class IOException;
-
-
#include <exception>
-
-
-
+/**
+ * Inidcates that an unrecoverable I/O failure occured.
+ */
class IOException : public std::exception{
public:
+ /**
+ * Creates a new IOException with the given message.
+ *
+ * @param message The message to associate with this exception.
+ */
IOException(const char* message);
+
+ /**
+ * Creates a new IOException with the given message and
+ * error value.
+ *
+ * @param message The message to associate with this exception.
+ * @param errorValue The integer code to associate with this exception.
+ */
IOException(const char* message, int errorValue);
+
+ /**
+ * Gets the message associated with this exception.
+ *
+ * @return The message associated with this exception.
+ */
const char* what();
+
+ /**
+ * Determines whether this exception indicates that an EOF
+ * was encountered.
+ *
+ * @return True if this exception indicates that an EOF was encountered.
+ * False otherwise.
+ */
virtual bool isEOF();
virtual ~IOException() throw ();
private:
View
@@ -10,8 +10,27 @@
#ifndef TIME_H_
#define TIME_H_
+/**
+ * Causes the current thread to sleep at least the
+ * given number of milliseconds.
+ *
+ * @param ms The number of milliseconds to sleep.
+ */
void sleep_ms(unsigned long ms);
+
+/**
+ * Retrieves the current time in milliseconds.
+ *
+ * @return The current time in milliseconds.
+ */
unsigned long currentTimeMillis();
+
+/**
+ * Writes a warning message to the standard error
+ * stream.
+ *
+ * @param message The string message to write.
+ */
void writeWarning(const char* message);
View
@@ -27,18 +27,25 @@ class ITable {
public:
/**
+ * Determines whether the given key is in this table.
+ *
* @param key the key to search for
* @return true if the table as a value assigned to the given key
*/
virtual bool ContainsKey(std::string key) = 0;
/**
+ * Determines whether there exists a non-empty subtable for this key
+ * in this table.
+ *
* @param key the key to search for
* @return true if there is a subtable with the key which contains at least one key/subtable of its own
*/
virtual bool ContainsSubTable(std::string key) = 0;
/**
+ * Gets the subtable in this table for the given name.
+ *
* @param key the name of the table relative to this one
* @return a sub table relative to this one
*/
@@ -47,13 +54,15 @@ class ITable {
/**
* Gets the value associated with a key as an object
+ *
* @param key the key of the value to look up
* @return the value associated with the given key
* @throws TableKeyNotDefinedException if there is no value associated with the given key
*/
virtual EntryValue GetValue(std::string key) = 0;
/**
* Put a value in the table
+ *
* @param key the key to be assigned to
* @param value the value that will be assigned
* @throws IllegalArgumentException when the value is not supported by the table
@@ -66,17 +75,22 @@ class ITable {
/**
* Put a number in the table
+ *
* @param key the key to be assigned to
* @param value the value that will be assigned
*/
virtual void PutNumber(std::string key, double value) = 0;
/**
+ * Gets the number associated with the given name.
+ *
* @param key the key to look up
* @return the value associated with the given key
* @throws TableKeyNotDefinedException if there is no value associated with the given key
*/
virtual double GetNumber(std::string key) = 0;
/**
+ * Gets the number associated with the given name.
+ *
* @param key the key to look up
* @param defaultValue the value to be returned if no value is found
* @return the value associated with the given key or the given default value if there is no value associated with the key
@@ -85,17 +99,24 @@ class ITable {
/**
* Put a std::string& in the table
+ *
* @param key the key to be assigned to
* @param value the value that will be assigned
*/
virtual void PutString(std::string key, std::string value) = 0;
+
/**
+ * Gets the string associated with the given name.
+ *
* @param key the key to look up
* @return the value associated with the given key
* @throws TableKeyNotDefinedException if there is no value associated with the given key
*/
virtual std::string GetString(std::string key) = 0;
+
/**
+ * Gets the string associated with the given name.
+ *
* @param key the key to look up
* @param defaultValue the value to be returned if no value is found
* @return the value associated with the given key or the given default value if there is no value associated with the key
@@ -104,53 +125,64 @@ class ITable {
/**
* Put a boolean in the table
+ *
* @param key the key to be assigned to
* @param value the value that will be assigned
*/
virtual void PutBoolean(std::string key, bool value) = 0;
+
/**
+ * Gets the boolean associated with the given name.
+ *
* @param key the key to look up
* @return the value associated with the given key
* @throws TableKeyNotDefinedException if there is no value associated with the given key
*/
virtual bool GetBoolean(std::string key) = 0;
+
/**
+ * Gets the boolean associated with the given name.
+ *
* @param key the key to look up
* @param defaultValue the value to be returned if no value is found
* @return the value associated with the given key or the given default value if there is no value associated with the key
*/
virtual bool GetBoolean(std::string key, bool defaultValue) = 0;
-
-
-
-
/**
* Add a listener for changes to the table
+ *
* @param listener the listener to add
*/
virtual void AddTableListener(ITableListener* listener) = 0;
+
/**
* Add a listener for changes to the table
+ *
* @param listener the listener to add
* @param immediateNotify if true then this listener will be notified of all current entries (marked as new)
*/
virtual void AddTableListener(ITableListener* listener, bool immediateNotify) = 0;
/**
* Add a listener for changes to a specific key the table
+ *
* @param key the key to listen for
* @param listener the listener to add
* @param immediateNotify if true then this listener will be notified of all current entries (marked as new)
*/
virtual void AddTableListener(std::string key, ITableListener* listener, bool immediateNotify) = 0;
+
/**
* This will immediately notify the listener of all current sub tables
+ *
* @param listener
*/
virtual void AddSubTableListener(ITableListener* listener) = 0;
+
/**
* Remove a listener from receiving table events
+ *
* @param listener the listener to be removed
*/
virtual void RemoveTableListener(ITableListener* listener) = 0;