90 using namespace std::chrono;
91 using namespace r_code;
92 using namespace r_exec;
97 lastInjectTime_ = Timestamp(seconds(0));
100 next_velocity_y_ = .1;
101 next_position_y_ = 1;
105 position_y_obj_ = NULL;
106 cart_position_y_obj_ = NULL;
107 position_property_ = NULL;
108 position_y_property_ = NULL;
109 velocity_y_property_ = NULL;
110 force_y_property_ = NULL;
111 theta_y_property_ = NULL;
112 omega_y_property_ = NULL;
113 primary_group_ = NULL;
114 ready_opcode_ = 0xFFFF;
115 set_velocity_y_opcode_ = 0xFFFF;
116 set_force_y_opcode_ = 0xFFFF;
117 move_y_plus_opcode_ = 0xFFFF;
118 move_y_minus_opcode_ = 0xFFFF;
119 lastCommandTime_ = Timestamp(seconds(0));
121 for (
int i = 0; i <= 9; ++i)
123 discretePositionObj_ = NULL;
124 discretePosition_ = NULL;
125 nextDiscretePosition_ = NULL;
129 float max_force = 20;
132 delete timeTickThread_;
136 (
const vector<Code*> *objects, uint32 stdin_oid, uint32 stdout_oid,
143 ready_opcode_ = r_exec::GetOpcode(
"ready");
144 set_velocity_y_opcode_ = r_exec::GetOpcode(
"set_velocity_y");
145 set_force_y_opcode_ = r_exec::GetOpcode(
"set_force_y");
146 move_y_plus_opcode_ = r_exec::GetOpcode(
"move_y_plus");
147 move_y_minus_opcode_ = r_exec::GetOpcode(
"move_y_minus");
150 position_property_ = S::find_object(objects,
"position");
151 position_y_property_ = S::find_object(objects,
"position_y");
152 velocity_y_property_ = S::find_object(objects,
"velocity_y");
153 force_y_property_ = S::find_object(objects,
"force_y");
154 theta_y_property_ = S::find_object(objects,
"theta_y");
155 omega_y_property_ = S::find_object(objects,
"omega_y");
156 primary_group_ = S::find_object(objects,
"primary");
159 for (
int i = 0; i <= 9; ++i)
160 yEnt_[i] = S::find_object(objects, (
"y" + to_string(i)).c_str());
166 uint16
function = (command->code(CMD_FUNCTION).atom_ >> 8) & 0x000000FF;
168 if (
function == ready_opcode_) {
169 uint16 args_set_index = command->code(CMD_ARGS).asIndex();
170 if (command->code_size() >= 2 && command->code(args_set_index + 1).getDescriptor() == Atom::I_PTR &&
171 command->code(command->code(args_set_index + 1).asIndex()).getDescriptor() == Atom::STRING) {
172 string identifier = Utils::GetString(&command->code(command->code(args_set_index + 1).asIndex()));
174 if (identifier ==
"ball") {
175 if (!(command->code_size() >= 3 && command->code(args_set_index + 2).getDescriptor() == Atom::R_PTR &&
176 command->references_size() > command->code(args_set_index + 2).asIndex())) {
177 cout <<
"WARNING: Cannot get the object for ready \"ball\"" << endl;
180 if (!velocity_y_property_) {
181 cout <<
"WARNING: Can't find the velocity_y property" << endl;
184 if (!position_y_property_) {
185 cout <<
"WARNING: Can't find the position_y property" << endl;
189 Code* obj = command->get_reference(command->code(args_set_index + 2).asIndex());
190 if (!position_y_obj_) {
192 position_y_obj_ = obj;
193 startTimeTickThread();
196 if (position_y_obj_ != obj)
202 if (identifier ==
"cart-pole") {
203 if (!(command->code_size() >= 3 && command->code(args_set_index + 2).getDescriptor() == Atom::R_PTR &&
204 command->references_size() > command->code(args_set_index + 2).asIndex())) {
205 cout <<
"WARNING: Cannot get the object for ready \"ball\"" << endl;
208 if (!velocity_y_property_) {
209 cout <<
"WARNING: Can't find the velocity_y property" << endl;
212 if (!position_y_property_) {
213 cout <<
"WARNING: Can't find the position_y property" << endl;
216 if (!force_y_property_) {
217 cout <<
"WARNING: Can't find the force_y property" << endl;
220 if (!omega_y_property_) {
221 cout <<
"WARNING: Can't find the omega_y property" << endl;
224 if (!theta_y_property_) {
225 cout <<
"WARNING: Can't find the theta_y property" << endl;
228 Code* obj = command->get_reference(command->code(args_set_index + 2).asIndex());
229 if (!cart_position_y_obj_) {
231 cart_position_y_obj_ = obj;
232 startTimeTickThread();
236 if (cart_position_y_obj_ != obj)
240 ofs.open(
"cart.out");
244 cout <<
"WARNING: Ignoring unrecognized ready command identifier: " << identifier << endl;
249 else if (
function == set_velocity_y_opcode_) {
250 if (!velocity_y_property_) {
251 cout <<
"WARNING: Can't find the velocity_y property" << endl;
254 if (!position_y_property_) {
255 cout <<
"WARNING: Can't find the position_y property" << endl;
259 auto now = r_exec::Now();
260 lastCommandTime_ = now;
261 uint16 args_set_index = command->code(CMD_ARGS).asIndex();
262 Code* obj = command->get_reference(
263 command->code(args_set_index + 1).asIndex());
265 if (!position_y_obj_) {
267 position_y_obj_ = obj;
268 startTimeTickThread();
271 if (position_y_obj_ != obj)
276 velocity_y_ = command->code(args_set_index + 2).asFloat();
280 else if (
function == set_force_y_opcode_) {
281 if (!velocity_y_property_) {
282 cout <<
"WARNING: Can't find the velocity_y property" << endl;
285 if (!position_y_property_) {
286 cout <<
"WARNING: Can't find the position_y property" << endl;
289 if (!omega_y_property_) {
290 cout <<
"WARNING: Can't find the omega_y property" << endl;
293 if (!theta_y_property_) {
294 cout <<
"WARNING: Can't find the theta_y property" << endl;
297 if (!force_y_property_) {
298 cout <<
"WARNING: Can't find the force_y property" << endl;
301 auto now = r_exec::Now();
302 lastCommandTime_ = now;
303 uint16 args_set_index = command->code(CMD_ARGS).asIndex();
304 Code* obj = command->get_reference(
305 command->code(args_set_index + 1).asIndex());
307 if (!cart_position_y_obj_) {
309 cart_position_y_obj_ = obj;
310 startTimeTickThread();
313 if (cart_position_y_obj_ != obj)
318 float desired_force = command->code(args_set_index + 2).asFloat();
319 if ((desired_force > max_force) || (desired_force < -max_force)) {
320 if (desired_force > max_force)
321 desired_force = max_force;
322 else if (desired_force < -max_force)
323 desired_force = -max_force;
325 force_y_ = desired_force;
328 AccCommand = set_force_y_opcode_;
331 cmdAcc->code(0) = Atom::Object(r_exec::GetOpcode(
"cmd"), 3);
332 cmdAcc->code(1) = Atom::DeviceFunction(AccCommand);
333 cmdAcc->code(2) = Atom::IPointer(4);
334 cmdAcc->code(3) = Atom::Float(1);
335 cmdAcc->code(4) = Atom::Set(2);
336 cmdAcc->code(5) = Atom::RPointer(0);
337 cmdAcc->code(6) = Atom::Float(force_y_);
338 cmdAcc->set_reference(0, cart_position_y_obj_);
343 force_y_ = desired_force;
348 else if (
function == move_y_plus_opcode_ ||
349 function == move_y_minus_opcode_) {
350 if (!position_property_) {
351 cout <<
"WARNING: Can't find the position property" << endl;
354 for (
int i = 0; i <= 9; ++i) {
356 cout <<
"WARNING: Can't find the entities y0, y1, etc." << endl;
361 auto now = r_exec::Now();
363 uint16 args_set_index = command->code(CMD_ARGS).asIndex();
364 Code* obj = command->get_reference(
365 command->code(args_set_index + 1).asIndex());
366 if (!discretePositionObj_) {
368 discretePositionObj_ = obj;
369 discretePosition_ = yEnt_[0];
370 startTimeTickThread();
373 if (discretePositionObj_ != obj)
378 if (nextDiscretePosition_)
383 lastCommandTime_ = now;
384 const int maxYPosition = 9;
385 if (
function == move_y_plus_opcode_) {
386 for (
int i = 0; i <= maxYPosition - 1; ++i) {
387 if (discretePosition_ == yEnt_[i])
388 nextDiscretePosition_ = yEnt_[i + 1];
391 else if (
function == move_y_minus_opcode_) {
392 for (
int i = 1; i <= maxYPosition; ++i) {
393 if (discretePosition_ == yEnt_[i])
394 nextDiscretePosition_ = yEnt_[i - 1];
405 auto now = r_exec::Now();
406 if (now <= lastInjectTime_ + S::get_sampling_period() * 8 / 10)
410 if (position_y_obj_) {
412 if (lastInjectTime_.time_since_epoch().count() == 0) {
416 position_y_ += velocity_y_ * duration_cast<microseconds>(now - lastInjectTime_).count();
418 lastInjectTime_ = now;
421 S::inject_marker_value_from_io_device(
422 position_y_obj_, velocity_y_property_, Atom::Float(velocity_y_),
423 now, now + S::get_sampling_period(), r_exec::View::SYNC_HOLD);
424 S::inject_marker_value_from_io_device(
425 position_y_obj_, position_y_property_, Atom::Float(position_y_),
426 now, now + S::get_sampling_period());
428 if (cart_position_y_obj_) {
430 if (lastInjectTime_.time_since_epoch().count() == 0) {
435 auto DeltaK = 1e-6 * duration_cast<microseconds>(now - lastInjectTime_).count();
436 float current_position_y;
437 float current_velocity_y;
438 float current_theta_y;
439 float current_omega_y;
441 current_position_y = next_position_y_;
442 current_velocity_y = next_velocity_y_;
443 current_theta_y = next_theta_y_;
444 current_omega_y = next_omega_y_;
447 next_velocity_y_ = (0.1 * force_y_) + current_velocity_y;
449 next_position_y_ = (0.5e-2 * force_y_) + (0.1 * current_velocity_y) + current_position_y;
451 next_omega_y_ = current_theta_y + 0.1 * force_y_ + current_omega_y;
453 next_theta_y_ = 0.0371943 * force_y_ + 1.05042 * current_theta_y + 0.101675 * current_omega_y;
470 lastInjectTime_ = now;
473 S::inject_marker_value_from_io_device(
474 cart_position_y_obj_, force_y_property_, Atom::Float(force_y_),
475 now, now + S::get_sampling_period());
476 S::inject_marker_value_from_io_device(
477 cart_position_y_obj_, velocity_y_property_, Atom::Float(next_velocity_y_),
478 now, now + S::get_sampling_period());
479 S::inject_marker_value_from_io_device(
480 cart_position_y_obj_, position_y_property_, Atom::Float(next_position_y_),
481 now, now + S::get_sampling_period());
482 S::inject_marker_value_from_io_device(
483 cart_position_y_obj_, theta_y_property_, Atom::Float(next_theta_y_),
484 now, now + S::get_sampling_period());
485 S::inject_marker_value_from_io_device(
486 cart_position_y_obj_, omega_y_property_, Atom::Float(next_omega_y_),
487 now, now + S::get_sampling_period());
489 ofs << next_theta_y_ <<
"," << next_omega_y_ <<
"," << next_position_y_ <<
"," << next_velocity_y_ <<
"," << force_y_ << endl;
491 if (discretePositionObj_) {
493 if (nextDiscretePosition_ &&
494 now >= lastCommandTime_ + S::get_sampling_period() * 4 / 10) {
496 discretePosition_ = nextDiscretePosition_;
498 nextDiscretePosition_ = NULL;
501 lastInjectTime_ = now;
502 S::inject_marker_value_from_io_device(
503 discretePositionObj_, position_property_, discretePosition_,
504 now, now + S::get_sampling_period());
506 const microseconds babbleStopTime(3700000);
507 const int maxBabblePosition = 9;
508 if (now - Utils::GetTimeReference() < babbleStopTime) {
510 if (discretePosition_ == yEnt_[0])
513 else if (discretePosition_ == yEnt_[maxBabblePosition])
515 babbleState_ = maxBabblePosition + 1;
518 if (babbleState_ >= maxBabblePosition * 2)
523 if (babbleState_ >= 0 && babbleState_ <= maxBabblePosition - 1)
524 nextCommand = move_y_plus_opcode_;
526 nextCommand = move_y_minus_opcode_;
530 cmd->code(0) = Atom::Object(r_exec::GetOpcode(
"cmd"), 3);
531 cmd->code(1) = Atom::DeviceFunction(nextCommand);
532 cmd->code(2) = Atom::IPointer(4);
533 cmd->code(3) = Atom::Float(1);
534 cmd->code(4) = Atom::Set(1);
535 cmd->code(5) = Atom::RPointer(0);
536 cmd->set_reference(0, discretePositionObj_);
538 auto after = now + S::get_sampling_period() + 2 * Utils::GetTimeTolerance();
541 S::inject_fact_from_io_device(goal, after, now + S::get_sampling_period(), primary_group_);
546 template<
class O,
class S>
void
548 if (S::reduction_core_count_ == 0 && S::time_core_count_ == 0)
557 timeTickThread_ = Thread::New<_Thread>(timeTickRun,
this);
560 template<
class O,
class S> thread_ret thread_function_call
564 auto sampling_period = _Mem::Get()->get_sampling_period();
565 auto tickTime = r_exec::Now();
567 while (self->state_ == S::RUNNING) {
568 self->on_time_tick();
570 tickTime += sampling_period;
571 Thread::Sleep(tickTime - r_exec::Now());