ci_range_and_bearing_actuator.cpp
Go to the documentation of this file.
1 
8 
9 #ifdef ARGOS_WITH_LUA
10 #include <argos3/core/wrappers/lua/lua_utility.h>
11 #endif
12 
13 namespace argos {
14 
15  /****************************************/
16  /****************************************/
17 
18 #ifdef ARGOS_WITH_LUA
19  /*
20  * The stack can have one or two values
21  * - The case of one value is when you set an entire array
22  * - In the case of two values, you must have:
23  * 1. the idx of the data item to set
24  * 2. the value of the data item in the range [0,255]
25  */
26  int LuaRABSetData(lua_State* pt_lua_state) {
27  if(lua_gettop(pt_lua_state) == 1) {
28  /* Check parameters */
29  luaL_checktype(pt_lua_state, 1, LUA_TTABLE);
30  /* Get reference to actuator */
31  CCI_RangeAndBearingActuator* pcAct = CLuaUtility::GetDeviceInstance<CCI_RangeAndBearingActuator>(pt_lua_state, "range_and_bearing");
32  /* Check whether sizes match */
33  if(pcAct->GetSize() != lua_rawlen(pt_lua_state, -1)) {
34  return luaL_error(pt_lua_state, "robot.range_and_bearing.set_data(array) expects an array of %d numbers", pcAct->GetSize());
35  }
36  /* Fill up a byte array, checking that all elements are numbers */
37  CByteArray cBuf(pcAct->GetSize());
38  for(size_t i = 0; i < pcAct->GetSize(); ++i) {
39  lua_pushnumber(pt_lua_state, i+1);
40  lua_gettable(pt_lua_state, -2);
41  if(lua_type(pt_lua_state, -1) == LUA_TNUMBER) {
42  cBuf[i] = static_cast<UInt8>(lua_tonumber(pt_lua_state, -1));
43  lua_pop(pt_lua_state, 1);
44  }
45  else {
46  return luaL_error(pt_lua_state, "element #%d of the array is not a number", i+1);
47  }
48  }
49  /* Perform action */
50  pcAct->SetData(cBuf);
51  return 0;
52  }
53  else if(lua_gettop(pt_lua_state) == 2) {
54  /* Check parameters */
55  luaL_checktype(pt_lua_state, 1, LUA_TNUMBER);
56  luaL_checktype(pt_lua_state, 2, LUA_TNUMBER);
57  /* Get reference to actuator */
58  CCI_RangeAndBearingActuator* pcAct = CLuaUtility::GetDeviceInstance<CCI_RangeAndBearingActuator>(pt_lua_state, "range_and_bearing");
59  /* Check parameter values */
60  size_t unIdx = lua_tonumber(pt_lua_state, 1);
61  UInt8 unData = lua_tonumber(pt_lua_state, 2);
62  if(unIdx < 1 || unIdx > pcAct->GetSize()) {
63  return luaL_error(pt_lua_state, "passed index %d out of bounds [1,%d]", unIdx, pcAct->GetSize());
64  }
65  /* Perform action */
66  pcAct->SetData(unIdx-1, unData);
67  return 0;
68  }
69  else {
70  return luaL_error(pt_lua_state, "robot.range_and_bearing.set_data() expects either one or two arguments");
71  }
72  }
73 #endif
74 
75 #ifdef ARGOS_WITH_LUA
76  /*
77  * The stack must have no values
78  */
79  int LuaRABClearData(lua_State* pt_lua_state) {
80  /* Check parameters */
81  if(lua_gettop(pt_lua_state) != 0) {
82  return luaL_error(pt_lua_state, "robot.range_and_bearing.clear_data() expects no arguments");
83  }
84  /* Perform action */
85  CLuaUtility::GetDeviceInstance<CCI_RangeAndBearingActuator>(pt_lua_state, "range_and_bearing")->ClearData();
86  return 0;
87  }
88 #endif
89 
90  /****************************************/
91  /****************************************/
92 
94  return m_cData.Size();
95  }
96 
97  /****************************************/
98  /****************************************/
99 
101  UInt8 un_value) {
102  m_cData[un_idx] = un_value;
103  }
104 
105  /****************************************/
106  /****************************************/
107 
109  m_cData.Zero();
110  }
111 
112  /****************************************/
113  /****************************************/
114 
115 #ifdef ARGOS_WITH_LUA
116  void CCI_RangeAndBearingActuator::CreateLuaState(lua_State* pt_lua_state) {
117  CLuaUtility::StartTable(pt_lua_state, "range_and_bearing");
118  CLuaUtility::AddToTable(pt_lua_state, "_instance", this);
119  CLuaUtility::AddToTable(pt_lua_state, "set_data", &LuaRABSetData);
120  CLuaUtility::AddToTable(pt_lua_state, "clear_data", &LuaRABClearData);
121  CLuaUtility::EndTable(pt_lua_state);
122  }
123 #endif
124 
125  /****************************************/
126  /****************************************/
127 
129  if(m_cData.Size() == c_data.Size()) {
130  m_cData = c_data;
131  }
132  else {
133  THROW_ARGOSEXCEPTION("CCI_RangeAndBearingActuator::SetData() : data size does not match, expected " << m_cData.Size() << ", got " << c_data.Size());
134  }
135  }
136 
137  /****************************************/
138  /****************************************/
139 
140 }
#define THROW_ARGOSEXCEPTION(message)
This macro throws an ARGoS exception with the passed message.
unsigned char UInt8
8-bit unsigned integer.
Definition: datatypes.h:60
The namespace containing all the ARGoS related code.
Definition: ci_actuator.h:12
Byte array utility class.
Definition: byte_array.h:28
void Zero()
Sets the contents of the byte array to all zeros.
Definition: byte_array.cpp:81
size_t Size() const
Returns the current size of the byte array.
Definition: byte_array.h:66
static void EndTable(lua_State *pt_state)
Adds a table to the Lua stack.
static void AddToTable(lua_State *pt_state, const std::string &str_key, void *pt_data)
Adds a pointer to a chunk of data with the given string key to the table located at the top of the st...
static void StartTable(lua_State *pt_state, const std::string &str_key)
Adds a table with the given string key to the table located at the top of the stack.