Class: Orocos::TaskContext

Inherits:
TaskContextBase show all
Defined in:
lib/orocos/task_context.rb,
lib/orocos/async/orocos.rb,
ext/rorocos/rorocos.cc

Overview

A proxy for a remote task context. The communication between Ruby and the RTT component is done through the CORBA transport.

See README.txt for information on how you can manipulate a task context through this class.

The available information about this task context can be displayed using Ruby's pretty print library:

require 'pp'
pp task_object

Defined Under Namespace

Modules: StateReader

Constant Summary

Constants inherited from TaskContextBase

Orocos::TaskContextBase::RUNNING_STATES

Constants included from Namespace

Namespace::DELIMATOR

Instance Attribute Summary collapse

Attributes inherited from TaskContextBase

#attributes, #configuration_log, #current_state, #ior, #process, #properties, #state_symbols

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from TaskContextBase

#add_default_states, #available_states, #basename, connect_to, #doc, #doc?, #each_attribute, #each_input_port, #each_operation, #each_output_port, #each_port, #each_property, #error?, #error_state?, #exception?, #exception_state?, #fatal_error?, #fatal_error_state?, find_one_running, get, get_provides, #has_attribute?, #has_property?, #implements?, #info, #input_port, #input_port_model, #inspect, #method_missing, #model=, #name, #on_localhost?, #output_port, #output_port_model, #peek_current_state, #ports, #pre_operational?, #pretty_print, reachable?, #reachable?, #ready?, #running?, #runtime_error?, #runtime_state?, #state, #state_changed?, #states, #to_h, #toplevel_state

Methods included from Namespace

#basename, #map_to_namespace, #namespace, #namespace=, #same_namespace?, #split_name, split_name, validate_namespace_name, #verify_same_namespace

Methods included from PortsSearchable

#find_all_input_ports, #find_all_output_ports, #find_all_ports, #find_input_port, #find_output_port, #find_port

Constructor Details

#initialize(ior, name: do_real_name, model: nil, **other_options) ⇒ TaskContext

A new TaskContext instance representing the remote task context with the given IOR

If a remote task is only known by its name use Orocos.name_service to create an handle to the remote task.

Parameters:

  • ior (String)

    The IOR of the remote task.

  • options (Hash)

    The options.



135
136
137
138
139
140
141
142
# File 'lib/orocos/task_context.rb', line 135

def initialize(ior, name: do_real_name, model: nil, **other_options)
    super(name, model: model, **other_options)
    @ior = ior

    if process && (process.default_logger_name != name)
        self.logger = process.default_logger
    end
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class Orocos::TaskContextBase

Instance Attribute Details

#logger#log

The logger task that should be used to log data that concerns this task

Returns:

  • (#log)


122
123
124
# File 'lib/orocos/task_context.rb', line 122

def logger
  @logger
end

Class Method Details

.corba_wrap(m, *args) ⇒ Object

Automated wrapper to handle CORBA exceptions coming from the C extension



78
79
80
81
82
83
84
# File 'lib/orocos/task_context.rb', line 78

def self.corba_wrap(m, *args) # :nodoc:
    class_eval <<-EOD
    def #{m}(#{args.join(". ")})
        CORBA.refine_exceptions(self) { do_#{m}(#{args.join(", ")}) }
    end
    EOD
end

.new(*args) ⇒ Object

/



123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'ext/rorocos/rorocos.cc', line 123

VALUE task_context_create(int argc, VALUE *argv,VALUE klass)
{
    corba_must_be_initialized();

    // all parametes are forwarded to ruby initialize
    if(argc < 1)
        rb_raise(rb_eArgError, "no ior given");
    std::string ior(StringValueCStr(argv[0]));

    RTaskContext *context =  corba_blocking_fct_call_with_result(boost::bind(&CorbaAccess::createRTaskContext,CorbaAccess::instance(),ior));
    VALUE obj = simple_wrap(klass, context);
    rb_obj_call_init(obj,argc,argv);
    return obj;
}

.state_transition_call(m, expected_state, target_state) ⇒ Object



86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/orocos/task_context.rb', line 86

def self.state_transition_call(m, expected_state, target_state)
    class_eval <<-EOD, __FILE__, (__LINE__ + 1)
    def #{m}(wait_for_completion = true, polling = 0.05)
        if wait_for_completion
            current_state = peek_current_state
        end
        CORBA.refine_exceptions(self) do
            begin
                do_#{m}
            rescue Orocos::StateTransitionFailed => e
                current_state = rtt_state
                reason =
                    if current_state == :EXCEPTION
                        ". The task is in an exception state. You must call #reset_exception before trying again"
                    elsif current_state == :PRE_OPERATIONAL && '#{m}' == 'start'
                        ". The Task must be configured before it could started. Did you forgot to call configure on the task?"
                    elsif current_state != :#{expected_state}
                        ". Tasks must be in #{expected_state} state before calling #{m}, but was in \#{current_state}"
                    end

                raise e, "\#{e.message} the '\#{self.name}' task\#{ " of type \#{self.model.name}" if self.model}\#{reason}", e.backtrace
            end
        end
        if wait_for_completion
            while current_state == peek_current_state#{" && current_state != :#{target_state}" if target_state}
                sleep polling
            end
        end
    end
    EOD
end

Instance Method Details

#==(other) ⇒ Object



138
139
140
141
142
143
144
145
146
# File 'ext/rorocos/rorocos.cc', line 138

static VALUE task_context_equal_p(VALUE self, VALUE other)
{
    if (!rb_obj_is_kind_of(other, cTaskContext))
        return Qfalse;

    RTaskContext& self_  = get_wrapped<RTaskContext>(self);
    RTaskContext& other_ = get_wrapped<RTaskContext>(other);
    return self_.task->_is_equivalent(other_.task) ? Qtrue : Qfalse;
}

#apply_conf(section_names = Array.new, override = false) ⇒ Object

Applies the TaskContext configuration stored by the main configuration manager to the TaskContext

See also #load_conf and #Orocos.load_config_dir



305
306
307
# File 'lib/orocos/task_context.rb', line 305

def apply_conf(section_names = Array.new, override=false)
    Orocos.conf.apply(self, section_names, override)
end

#apply_conf_file(file, section_names = Array.new, override = false) ⇒ Object

Loads the configuration for the TaskContext from a file, into the main configuration manager and applies it to the TaskContext

See also #apply_conf and #Orocos.load_config_dir



292
293
294
295
# File 'lib/orocos/task_context.rb', line 292

def apply_conf_file(file,section_names=Array.new,override=false)
    Orocos.conf.load_file(file,model.name)
    apply_conf(section_names,override)
end

#attribute(name) ⇒ Object

Returns an Attribute object representing the given attribute

Raises NotFound if no such attribute exists.

Attributes can also be read and written by calling directly the relevant method on the task context:

task.attribute("myProperty").read
task.attribute("myProperty").write(value)

is equivalent to

task.myProperty
task.myProperty = value


436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
# File 'lib/orocos/task_context.rb', line 436

def attribute(name)
    name = name.to_s
    if a = attributes[name]
        if has_attribute?(name)
            return a
        else
            attributes.delete(name)
            raise Orocos::InterfaceObjectNotFound.new(self, name), "task #{self.name} does not have an attribute named #{name}", e.backtrace
        end
    end

    type_name = CORBA.refine_exceptions(self) do
        begin
            do_attribute_type_name(name)
        rescue ArgumentError => e
            raise Orocos::InterfaceObjectNotFound.new(self, name), "task #{self.name} does not have an attribute named #{name}", e.backtrace
        end
    end

    a = Attribute.new(self, name, type_name)
    if configuration_log
        create_property_log_stream(a)
        a.log_current_value
    end
    attributes[name] = a
end

#attribute_namesObject

Returns the array of the names of available attributes on this task context



415
416
417
418
419
# File 'lib/orocos/task_context.rb', line 415

def attribute_names
    CORBA.refine_exceptions(self) do
        do_attribute_names
    end
end

#callop(name, *args) ⇒ Object

Calls the required operation with the given argument

This is a shortcut for operation(name).calldop(*arguments)



579
580
581
# File 'lib/orocos/task_context.rb', line 579

def callop(name, *args)
    operation(name).callop(*args)
end

#cleanupObject

:method: cleanup

Cleans the component, i.e. do the transition from STATE_STOPPED into STATE_PRE_OPERATIONAL.

Raises StateTransitionFailed if the component was not in STATE_STOPPED state before the call. The component cannot refuse to perform the transition (but can take an arbitrarily long time to do it).



367
# File 'lib/orocos/task_context.rb', line 367

state_transition_call :cleanup, 'STOPPED', 'PRE_OPERATIONAL'

#configureObject

:method: configure

Configures the component, i.e. do the transition from STATE_PRE_OPERATIONAL into STATE_STOPPED.

Raises StateTransitionFailed if the component was not in STATE_PRE_OPERATIONAL state before the call, or if the component refused to do the transition (startHook() returned false)



323
# File 'lib/orocos/task_context.rb', line 323

state_transition_call :configure, 'PRE_OPERATIONAL', 'STOPPED'

#connect_to(sink, policy = Hash.new) ⇒ Object



625
626
627
628
629
630
631
# File 'lib/orocos/task_context.rb', line 625

def connect_to(sink, policy = Hash.new)
    port = find_output_port(sink.type, nil)
    if !port
        raise ArgumentError, "port #{sink.name} does not match any output port of #{name}"
    end
    port.connect_to(sink, policy)
end

#create_property_log_stream(p) ⇒ Object



251
252
253
254
255
256
257
258
# File 'lib/orocos/task_context.rb', line 251

def create_property_log_stream(p)
    stream_name = "#{self.name}.#{p.name}"
    if !configuration_log.has_stream?(stream_name)
        p.log_stream = configuration_log.create_stream(stream_name, p.type, p.)
    else
        p.log_stream = configuration_log.stream(stream_name)
    end
end

#disconnect_from(sink, policy = Hash.new) ⇒ Object



633
634
635
636
637
638
639
640
# File 'lib/orocos/task_context.rb', line 633

def disconnect_from(sink, policy = Hash.new)
    each_output_port do |out_port|
        if out_port.type == sink.type
            out_port.disconnect_from(sink)
        end
    end
    nil
end

#do_attribute_namesObject



217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
# File 'ext/rorocos/rorocos.cc', line 217

static VALUE task_context_attribute_names(VALUE self)
{
    RTaskContext& context = get_wrapped<RTaskContext>(self);

    VALUE result = rb_ary_new();
    RTT::corba::CConfigurationInterface::CAttributeNames_var names =
        corba_blocking_fct_call_with_result(bind(&_objref_CConfigurationInterface::getAttributeList,(_objref_CConfigurationInterface*)context.main_service));
    for (unsigned int i = 0; i != names->length(); ++i)
    {
        #if RTT_VERSION_GTE(2,9,0)
            CORBA::String_var name = names[i].name;
        #else
            CORBA::String_var name = names[i];
        #endif
        rb_ary_push(result, rb_str_new2(name));
    }
    return result;
}

#do_attribute_read(property_name, type_name, rb_typelib_value) ⇒ Object



158
159
160
161
162
163
164
165
166
167
168
# File 'ext/rorocos/datahandling.cc', line 158

static VALUE attribute_do_read(VALUE rbtask, VALUE property_name, VALUE type_name, VALUE rb_typelib_value)
{
    RTaskContext& task = get_wrapped<RTaskContext>(rbtask);
    Typelib::Value value = typelib_get(rb_typelib_value);

    CORBA::Any_var corba_value = corba_blocking_fct_call_with_result(boost::bind(&_objref_CConfigurationInterface::getAttribute,
                (_objref_CConfigurationInterface*)task.main_service,
                StringValuePtr(property_name)));
    corba_to_ruby(StringValuePtr(type_name), value, corba_value);
    return rb_typelib_value;
}

#do_attribute_read_string(property_name) ⇒ Object



144
145
146
147
148
149
150
151
152
153
154
155
156
# File 'ext/rorocos/datahandling.cc', line 144

static VALUE attribute_do_read_string(VALUE rbtask, VALUE property_name)
{
    RTaskContext& task = get_wrapped<RTaskContext>(rbtask);

    CORBA::Any_var corba_value = corba_blocking_fct_call_with_result(boost::bind(&_objref_CConfigurationInterface::getAttribute,
                                                                    (_objref_CConfigurationInterface*)task.main_service,
                                                                    StringValuePtr(property_name)));
    char const* result = 0;
    if (!(corba_value >>= result))
        rb_raise(rb_eArgError, "no such attribute");
    VALUE rb_result = rb_str_new2(result);
    return rb_result;
}

#do_attribute_type_name(name) ⇒ Object



174
175
176
177
178
179
180
181
182
183
184
185
186
# File 'ext/rorocos/rorocos.cc', line 174

static VALUE task_context_attribute_type_name(VALUE self, VALUE name)
{
    RTaskContext& context = get_wrapped<RTaskContext>(self);
    std::string const expected_name = StringValuePtr(name);
    CORBA::String_var attribute_type_name =
        corba_blocking_fct_call_with_result(bind(&_objref_CConfigurationInterface::getAttributeTypeName,(_objref_CConfigurationInterface*)context.main_service,StringValuePtr(name)));
    std::string type_name = std::string(attribute_type_name);
    if (type_name != "na")
        return rb_str_new(type_name.c_str(), type_name.length());

    rb_raise(rb_eArgError, "no such attribute %s", StringValuePtr(name));
    return Qfalse;
}

#do_attribute_write(property_name, type_name, rb_typelib_value) ⇒ Object



184
185
186
187
188
189
190
191
192
193
194
195
196
# File 'ext/rorocos/datahandling.cc', line 184

static VALUE attribute_do_write(VALUE rbtask, VALUE property_name, VALUE type_name, VALUE rb_typelib_value)
{
    RTaskContext& task = get_wrapped<RTaskContext>(rbtask);
    Typelib::Value value = typelib_get(rb_typelib_value);

    CORBA::Any_var corba_value = ruby_to_corba(StringValuePtr(type_name), value);
    bool result = corba_blocking_fct_call_with_result(boost::bind(&_objref_CConfigurationInterface::setAttribute,
                (_objref_CConfigurationInterface*)task.main_service,
                StringValuePtr(property_name),corba_value));
    if(!result)
        rb_raise(rb_eArgError, "failed to write the attribute");
    return Qnil;
}

#do_attribute_write_string(property_name, rb_value) ⇒ Object



170
171
172
173
174
175
176
177
178
179
180
181
182
# File 'ext/rorocos/datahandling.cc', line 170

static VALUE attribute_do_write_string(VALUE rbtask, VALUE property_name, VALUE rb_value)
{
    RTaskContext& task = get_wrapped<RTaskContext>(rbtask);

    CORBA::Any_var corba_value = new CORBA::Any;
    corba_value <<= StringValuePtr(rb_value);
    bool result = corba_blocking_fct_call_with_result(boost::bind(&_objref_CConfigurationInterface::setAttribute,
                (_objref_CConfigurationInterface*)task.main_service,
                StringValuePtr(property_name),corba_value));
    if(!result)
        rb_raise(rb_eArgError, "failed to write the attribute");
    return Qnil;
}

#do_cleanupObject

Do the transition between STATE_STOPPED and STATE_PRE_OPERATIONAL



371
372
373
374
# File 'ext/rorocos/rorocos.cc', line 371

static VALUE task_context_cleanup(VALUE task)
{
    return call_checked_state_change(task, "failed to cleanup", &RTT::corba::_objref_CTaskContext::cleanup);
}

#do_configureObject

Do the transition between STATE_PRE_OPERATIONAL and STATE_STOPPED



353
354
355
356
# File 'ext/rorocos/rorocos.cc', line 353

static VALUE task_context_configure(VALUE task)
{
    return call_checked_state_change(task, "failed to configure", &RTT::corba::_objref_CTaskContext::configure);
}

#do_has_operation?(name) ⇒ Boolean

Returns:

  • (Boolean)


167
168
169
170
171
172
# File 'ext/rorocos/rorocos.cc', line 167

static VALUE task_context_has_operation_p(VALUE self, VALUE name)
{
    RTaskContext& context = get_wrapped<RTaskContext>(self);
    corba_blocking_fct_call(bind(&_objref_COperationInterface::getResultType,(_objref_COperationInterface*)context.main_service,StringValuePtr(name)));
    return Qtrue;
}

#do_has_port?(name) ⇒ Boolean

Returns:

  • (Boolean)


154
155
156
157
158
159
# File 'ext/rorocos/rorocos.cc', line 154

static VALUE task_context_has_port_p(VALUE self, VALUE name)
{
    RTaskContext& context = get_wrapped<RTaskContext>(self);
    corba_blocking_fct_call(bind(&_objref_CDataFlowInterface::getPortType,(CDataFlowInterface_ptr)context.ports,StringValuePtr(name)));
    return Qtrue;
}

#do_operation_call(name, result_type_name, result, args_type_names, args) ⇒ Object



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'ext/rorocos/operations.cc', line 69

static VALUE operation_call(VALUE task_, VALUE name, VALUE result_type_name, VALUE result, VALUE args_type_names, VALUE args)
{
    RTaskContext& task = get_wrapped<RTaskContext>(task_);
    CAnyArguments_var corba_args = corba_args_from_ruby(args_type_names, args);

    CORBA::Any_var corba_result = corba_blocking_fct_call_with_result(boost::bind(&_objref_COperationInterface::callOperation,
                (_objref_COperationInterface*)task.main_service,
                StringValuePtr(name),corba_args));

    if (!NIL_P(result))
    {
        Typelib::Value v = typelib_get(result);
        corba_to_ruby(StringValuePtr(result_type_name), v, corba_result);
    }
    corba_args_to_ruby(args_type_names, args, corba_args);
    return result;
}

#do_operation_namesObject



236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
# File 'ext/rorocos/rorocos.cc', line 236

static VALUE task_context_operation_names(VALUE self)
{
    RTaskContext& context = get_wrapped<RTaskContext>(self);

    VALUE result = rb_ary_new();
    #if RTT_VERSION_GTE(2,9,0)
        RTT::corba::COperationInterface::COperationDescriptions_var names =
                corba_blocking_fct_call_with_result(bind(&_objref_COperationInterface::getOperations,(_objref_COperationInterface*)context.main_service));
    #else
        RTT::corba::COperationInterface::COperationList_var names =
                corba_blocking_fct_call_with_result(bind(&_objref_COperationInterface::getOperations,(_objref_COperationInterface*)context.main_service));
    #endif

    for (unsigned int i = 0; i != names->length(); ++i)
    {
        #if RTT_VERSION_GTE(2,9,0)
            CORBA::String_var name = names[i].name;
        #else
            CORBA::String_var name = names[i];
        #endif
        rb_ary_push(result, rb_str_new2(name));
    }
    return result;
}

#do_operation_send(name, args_type_names, args) ⇒ Object



105
106
107
108
109
110
111
112
113
114
# File 'ext/rorocos/operations.cc', line 105

static VALUE operation_send(VALUE task_, VALUE name, VALUE args_type_names, VALUE args)
{
    RTaskContext& task = get_wrapped<RTaskContext>(task_);
    CAnyArguments_var corba_args = corba_args_from_ruby(args_type_names, args);

    RTT::corba::CSendHandle_var corba_result = corba_blocking_fct_call_with_result(boost::bind(&_objref_COperationInterface::sendOperation,
                (_objref_COperationInterface*)task.main_service,
                StringValuePtr(name),corba_args));
    return simple_wrap(cSendHandle, new RSendHandle(corba_result));
}

#do_port(name, model) ⇒ Object

/



268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
# File 'ext/rorocos/rorocos.cc', line 268

static VALUE task_context_do_port(VALUE self, VALUE name, VALUE model)
{
    RTaskContext& context = get_wrapped<RTaskContext>(self);
    RTT::corba::CPortType port_type;
    CORBA::String_var    type_name;
    port_type = corba_blocking_fct_call_with_result(bind(&_objref_CDataFlowInterface::getPortType,(_objref_CDataFlowInterface*)context.ports,StringValuePtr(name)));
    type_name = corba_blocking_fct_call_with_result(bind(&_objref_CDataFlowInterface::getDataType,(_objref_CDataFlowInterface*)context.ports,StringValuePtr(name)));

    VALUE obj = Qnil;
    VALUE args[4] = { self, rb_str_dup(name), rb_str_new2(type_name), model };
    if (port_type == RTT::corba::CInput)
        obj = rb_class_new_instance(4, args, cInputPort);
    else if (port_type == RTT::corba::COutput)
        obj = rb_class_new_instance(4, args, cOutputPort);

    return obj;
}

#do_port_namesObject



308
309
310
311
312
313
314
315
316
317
318
319
# File 'ext/rorocos/rorocos.cc', line 308

static VALUE task_context_port_names(VALUE self)
{
    VALUE result = rb_ary_new();
    RTaskContext& context = get_wrapped<RTaskContext>(self);
    RTT::corba::CDataFlowInterface::CPortNames_var ports =
        corba_blocking_fct_call_with_result(bind(&_objref_CDataFlowInterface::getPorts,(_objref_CDataFlowInterface*)context.ports));

    for (unsigned int i = 0; i < ports->length(); ++i)
        rb_ary_push(result, rb_str_new2(ports[i]));

    return result;
}

#do_property_namesObject



202
203
204
205
206
207
208
209
210
211
212
213
214
215
# File 'ext/rorocos/rorocos.cc', line 202

static VALUE task_context_property_names(VALUE self)
{
    RTaskContext& context = get_wrapped<RTaskContext>(self);

    VALUE result = rb_ary_new();
    RTT::corba::CConfigurationInterface::CPropertyNames_var names =
        corba_blocking_fct_call_with_result(bind(&_objref_CConfigurationInterface::getPropertyList,(_objref_CConfigurationInterface*)context.main_service));
    for (unsigned int i = 0; i != names->length(); ++i)
    {
        CORBA::String_var name = names[i].name;
        rb_ary_push(result, rb_str_new2(name));
    }
    return result;
}

#do_property_read(property_name, type_name, rb_typelib_value) ⇒ Object



104
105
106
107
108
109
110
111
112
113
114
# File 'ext/rorocos/datahandling.cc', line 104

static VALUE property_do_read(VALUE rbtask, VALUE property_name, VALUE type_name, VALUE rb_typelib_value)
{
    RTaskContext& task = get_wrapped<RTaskContext>(rbtask);
    Typelib::Value value = typelib_get(rb_typelib_value);

    CORBA::Any_var corba_value = corba_blocking_fct_call_with_result(boost::bind(&_objref_CConfigurationInterface::getProperty,
                (_objref_CConfigurationInterface*)task.main_service,
                StringValuePtr(property_name)));
    corba_to_ruby(StringValuePtr(type_name), value, corba_value);
    return rb_typelib_value;
}

#do_property_read_string(property_name) ⇒ Object



90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'ext/rorocos/datahandling.cc', line 90

static VALUE property_do_read_string(VALUE rbtask, VALUE property_name)
{
    RTaskContext& task = get_wrapped<RTaskContext>(rbtask);

    CORBA::Any_var corba_value = corba_blocking_fct_call_with_result(boost::bind(&_objref_CConfigurationInterface::getProperty,
                                                                    (_objref_CConfigurationInterface*)task.main_service,
                                                                    StringValuePtr(property_name)));
    char const* result = 0;
    if (!(corba_value >>= result))
        rb_raise(rb_eArgError, "no such property");
    VALUE rb_result = rb_str_new2(result);
    return rb_result;
}

#do_property_type_name(name) ⇒ Object



188
189
190
191
192
193
194
195
196
197
198
199
200
# File 'ext/rorocos/rorocos.cc', line 188

static VALUE task_context_property_type_name(VALUE self, VALUE name)
{
    RTaskContext& context = get_wrapped<RTaskContext>(self);
    std::string const expected_name = StringValuePtr(name);
    CORBA::String_var attribute_type_name =
        corba_blocking_fct_call_with_result(bind(&_objref_CConfigurationInterface::getPropertyTypeName,(_objref_CConfigurationInterface*)context.main_service,StringValuePtr(name)));
    std::string type_name = std::string(attribute_type_name);
    if (type_name != "na")
        return rb_str_new(type_name.c_str(), type_name.length());

    rb_raise(rb_eArgError, "no such property %s", StringValuePtr(name));
    return Qfalse;
}

#do_property_write(property_name, type_name, rb_typelib_value) ⇒ Object



130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'ext/rorocos/datahandling.cc', line 130

static VALUE property_do_write(VALUE rbtask, VALUE property_name, VALUE type_name, VALUE rb_typelib_value)
{
    RTaskContext& task = get_wrapped<RTaskContext>(rbtask);
    Typelib::Value value = typelib_get(rb_typelib_value);

    CORBA::Any_var corba_value = ruby_to_corba(StringValuePtr(type_name), value);
    bool result = corba_blocking_fct_call_with_result(boost::bind(&_objref_CConfigurationInterface::setProperty,
                (_objref_CConfigurationInterface*)task.main_service,
                StringValuePtr(property_name),corba_value));
    if(!result)
        rb_raise(rb_eArgError, "failed to write the property");
    return Qnil;
}

#do_property_write_string(property_name, rb_value) ⇒ Object



116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'ext/rorocos/datahandling.cc', line 116

static VALUE property_do_write_string(VALUE rbtask, VALUE property_name, VALUE rb_value)
{
    RTaskContext& task = get_wrapped<RTaskContext>(rbtask);

    CORBA::Any_var corba_value = new CORBA::Any;
    corba_value <<= StringValuePtr(rb_value);
    bool result = corba_blocking_fct_call_with_result(boost::bind(&_objref_CConfigurationInterface::setProperty,
                (_objref_CConfigurationInterface*)task.main_service,
                StringValuePtr(property_name),corba_value));
    if(!result)
        rb_raise(rb_eArgError, "failed to write the property");
    return Qnil;
}

#do_real_nameObject



161
162
163
164
165
# File 'ext/rorocos/rorocos.cc', line 161

static VALUE task_context_real_name(VALUE self)
{
    RTaskContext& context = get_wrapped<RTaskContext>(self);
    return rb_str_new2(context.name.c_str());
}

#do_reset_exceptionObject

Do the transition between STATE_EXCEPTION and STATE_STOPPED



377
378
379
380
# File 'ext/rorocos/rorocos.cc', line 377

static VALUE task_context_reset_exception(VALUE task)
{
    return call_checked_state_change(task, "failed to transition from the Exception state to Stopped", &RTT::corba::_objref_CTaskContext::resetException);
}

#do_startObject

Do the transition between STATE_STOPPED and STATE_RUNNING



359
360
361
362
# File 'ext/rorocos/rorocos.cc', line 359

static VALUE task_context_start(VALUE task)
{
    return call_checked_state_change(task, "failed to start", &RTT::corba::_objref_CTaskContext::start);
}

#do_stateObject

/



337
338
339
340
341
# File 'ext/rorocos/rorocos.cc', line 337

static VALUE task_context_state(VALUE task)
{
    RTaskContext& context = get_wrapped<RTaskContext>(task);
    return INT2FIX(corba_blocking_fct_call_with_result(boost::bind(&_objref_CTaskContext::getTaskState,(CTaskContext_ptr)context.task)));
}

#do_stopObject

Do the transition between STATE_RUNNING and STATE_STOPPED



365
366
367
368
# File 'ext/rorocos/rorocos.cc', line 365

static VALUE task_context_stop(VALUE task)
{
    return call_checked_state_change(task, "failed to stop", &RTT::corba::_objref_CTaskContext::stop);
}

#has_operation?(name) ⇒ Boolean

Returns true if this task context has a command with the given name

Returns:

  • (Boolean)


370
371
372
373
374
375
376
377
378
379
# File 'lib/orocos/task_context.rb', line 370

def has_operation?(name)
    name = name.to_s
    CORBA.refine_exceptions(self) do
        begin
            do_has_operation?(name)
        rescue Orocos::NotFound
            false
        end
    end
end

#has_port?(name) ⇒ Boolean

Returns true if this task context has a port with the given name

Returns:

  • (Boolean)


382
383
384
385
386
387
388
389
390
391
# File 'lib/orocos/task_context.rb', line 382

def has_port?(name)
    name = name.to_s
    CORBA.refine_exceptions(self) do
        begin
            do_has_port?(name)
        rescue Orocos::NotFound
            false
        end
    end
end

#log_all_configuration(logfile) ⇒ Object

Tell the task to use the given Pocolog::Logfile object to log all changes to its properties



262
263
264
265
266
267
268
# File 'lib/orocos/task_context.rb', line 262

def log_all_configuration(logfile)
    @configuration_log = logfile
    each_property do |p|
        create_property_log_stream(p)
        p.log_current_value
    end
end

#log_all_ports(options = Hash.new) ⇒ Set<String,String>

Connects all ports of the task with the logger of the deployment task.log_all_ports(:exclude_ports => “frame”)

Examples:

logging all ports beside a port called frame

Parameters:

  • options (Hash) (defaults to: Hash.new)

    option hash to exclude specific ports

Options Hash (options):

  • :exclude_ports (String, Array<String>)

    The name of the excluded ports

Returns:

  • (Set<String,String>)

    Sets of task and port names



238
239
240
241
242
243
244
245
246
247
248
249
# File 'lib/orocos/task_context.rb', line 238

def log_all_ports(options = Hash.new)
    # Right now, the only allowed option is :exclude_ports
    options, logger_options = Kernel.filter_options options,:exclude_ports => nil
    exclude_ports = Array(options[:exclude_ports])

    logger_options[:tasks] = Regexp.new(basename)
    ports = Orocos.log_all_process_ports(process,logger_options) do |port|
        !exclude_ports.include? port.name
    end
    raise "#{name}: no ports were selected for logging" if ports.empty?
    ports
end

#modelObject

Returns the Orogen specification object for this task's model. It will return a default model if the remote task does not respond to getModelName or the description file cannot be found.

See also #info



595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
# File 'lib/orocos/task_context.rb', line 595

def model
    model = super
    if model
        return model
    end

    model_name = begin
                     self.getModelName
                 rescue NoMethodError
                     nil
                 end

    self.model =
        if !model_name
            if name !~ /.*orocosrb_(\d+)$/
                Orocos.warn "#{name} is a task context not generated by orogen, using default task model"
            end
            Orocos.create_orogen_task_context_model(name)
        elsif model_name.empty?
            Orocos.create_orogen_task_context_model
        else
            begin
                Orocos.default_loader.task_model_from_name(model_name)
            rescue OroGen::NotFound
                Orocos.warn "#{name} is a task context of class #{model_name}, but I cannot find the description for it, falling back"
                Orocos.create_orogen_task_context_model(model_name)
            end
        end
end

#operation(name) ⇒ Object

Returns an Operation object that represents the given method on the remote component.

Raises NotFound if no such operation exists.



564
565
566
567
568
569
570
571
572
573
574
# File 'lib/orocos/task_context.rb', line 564

def operation(name)
    name = name.to_s
    CORBA.refine_exceptions(self) do
        return_types = operation_return_types(name)
        arguments = operation_argument_types(name)
        Operation.new(self, name, return_types, arguments)
    end

rescue Orocos::NotFound => e
    raise Orocos::InterfaceObjectNotFound.new(self, name), "task #{self.name} does not have an operation named #{name}", e.backtrace
end

#operation_argument_types(opname) ⇒ Object



161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
# File 'ext/rorocos/operations.cc', line 161

static VALUE operation_argument_types(VALUE task_, VALUE opname)
{
    RTaskContext& task = get_wrapped<RTaskContext>(task_);

    VALUE result = rb_ary_new();

    #if RTT_VERSION_GTE(2,9,0)
        RTT::corba::CArgumentDescriptions_var args = corba_blocking_fct_call_with_result(boost::bind(&_objref_COperationInterface::getArguments,
                (_objref_COperationInterface*)task.main_service,StringValuePtr(opname)));
    #else
        RTT::corba::CDescriptions_var args = corba_blocking_fct_call_with_result(boost::bind(&_objref_COperationInterface::getArguments,
                (_objref_COperationInterface*)task.main_service,StringValuePtr(opname)));
    #endif

    for (unsigned int i = 0; i < args->length(); ++i)
    {
        RTT::corba::CArgumentDescription arg =
            args[i];
        VALUE tuple = rb_ary_new();
        rb_ary_push(tuple, rb_str_new2(arg.name));
        rb_ary_push(tuple, rb_str_new2(arg.description));
        rb_ary_push(tuple, rb_str_new2(arg.type));
        rb_ary_push(result, tuple);
    }
    return result;
    return Qnil; // never reached
}

#operation_namesObject

Returns the array of the names of available operations on this task context



395
396
397
398
399
400
401
# File 'lib/orocos/task_context.rb', line 395

def operation_names
    CORBA.refine_exceptions(self) do
        do_operation_names.each do |str|
            str.force_encoding('ASCII') if str.respond_to?(:force_encoding)
        end
    end
end

#operation_return_types(opname) ⇒ Object



140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
# File 'ext/rorocos/operations.cc', line 140

static VALUE operation_return_types(VALUE task_, VALUE opname)
{
    RTaskContext& task = get_wrapped<RTaskContext>(task_);

    VALUE result = rb_ary_new();
        int retcount = corba_blocking_fct_call_with_result(boost::bind(&_objref_COperationInterface::getCollectArity,
                (_objref_COperationInterface*)task.main_service,StringValuePtr(opname)));

        CORBA::String_var type_name = corba_blocking_fct_call_with_result(boost::bind(&_objref_COperationInterface::getResultType,
                (_objref_COperationInterface*)task.main_service,StringValuePtr(opname)));
        rb_ary_push(result, rb_str_new2(type_name));

        for (int i = 0; i < retcount - 1; ++i)
        {
            type_name = corba_blocking_fct_call_with_result(boost::bind(&_objref_COperationInterface::getCollectType,
                (_objref_COperationInterface*)task.main_service,StringValuePtr(opname),i+1));
            rb_ary_push(result, rb_str_new2(type_name));
        }
        return result;
}

#peek_stateObject

Reads all state transitions that have been announced by the task and pushes them to @state_queue

The following call to #state will first look at @state_queue before accessing the task context



195
196
197
198
199
200
201
202
203
204
205
206
207
208
# File 'lib/orocos/task_context.rb', line 195

def peek_state
    if model && model.extended_state_support?
	    	if !@state_reader || !@state_reader.connected?
            @state_reader = state_reader
            @state_queue << rtt_state
		end
        while new_state = @state_reader.read_new
            @state_queue << new_state
        end
    else
        super
    end
    @state_queue
end

#pingObject



144
145
146
147
# File 'lib/orocos/task_context.rb', line 144

def ping
    rtt_state
    nil
end

#port(name, verify = true) ⇒ Object

Returns an object that represents the given port on the remote task context. The returned object is either an InputPort or an OutputPort

Raises NotFound if no such port exists.

Ports can also be accessed by calling directly the relevant method on the task context:

task.port("myPort")

is equivalent to

task.myPort


534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
# File 'lib/orocos/task_context.rb', line 534

def port(name, verify = true)
    name = name.to_str
    CORBA.refine_exceptions(self) do
        if @ports[name]
            if !verify || has_port?(name) # Check that this port is still valid
                @ports[name]
            else
                @ports.delete(name)
                raise NotFound, "no port named '#{name}' on task '#{self.name}'"
            end
        else
            @ports[name] = raw_port(name)
        end
    end
end

#port_namesObject

Returns the names of all the ports defined on this task context



552
553
554
555
556
557
558
# File 'lib/orocos/task_context.rb', line 552

def port_names
    CORBA.refine_exceptions(self) do
        do_port_names.each do |str|
            str.force_encoding('ASCII') if str.respond_to?(:force_encoding)
        end
    end
end

#property(name) ⇒ Object

Returns a Property object representing the given property

Raises NotFound if no such property exists.

Ports can also be accessed by calling directly the relevant method on the task context:

task.property("myProperty").read
task.property("myProperty").write(value)

is equivalent to

task.myProperty
task.myProperty = value


490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
# File 'lib/orocos/task_context.rb', line 490

def property(name)
    name = name.to_s
    if p = properties[name]
        if has_property?(name)
            return p
        else
            properties.delete(name)
            raise Orocos::InterfaceObjectNotFound.new(self, name), "task #{self.name} does not have a property named #{name}", e.backtrace
        end
    end

    p = raw_property(name)
    if configuration_log
        create_property_log_stream(p)
        p.log_current_value
    end
    properties[name] = p
end

#property_namesObject

Returns the array of the names of available properties on this task context



405
406
407
408
409
410
411
# File 'lib/orocos/task_context.rb', line 405

def property_names
    CORBA.refine_exceptions(self) do
        do_property_names.each do |str|
            str.force_encoding('ASCII') if str.respond_to?(:force_encoding)
        end
    end
end

#raw_port(name) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Resolve a Port object for the given port name



512
513
514
515
516
517
518
# File 'lib/orocos/task_context.rb', line 512

def raw_port(name)
    port_model = model.find_port(name)
    do_port(name, port_model)

rescue Orocos::NotFound => e
    raise Orocos::InterfaceObjectNotFound.new(self, name), "task #{self.name} does not have a port named #{name}", e.backtrace
end

#raw_property(name) ⇒ Object

Return the property object without caching nor validation



464
465
466
467
468
469
470
471
472
473
# File 'lib/orocos/task_context.rb', line 464

def raw_property(name)
    type_name = CORBA.refine_exceptions(self) do
        begin
            do_property_type_name(name)
        rescue ArgumentError => e
            raise Orocos::InterfaceObjectNotFound.new(self, name), "task #{self.name} does not have a property named #{name}", e.backtrace
        end
    end
    Property.new(self, name, type_name)
end

#reset_exceptionObject

:method: reset_exception

Recover from the exception state. It does the transition from STATE_EXCEPTION to either STATE_STOPPED if the component does not need any configuration or STATE_PRE_OPERATIONAL otherwise

Raises StateTransitionFailed if the component was not in a proper state before the call.



345
# File 'lib/orocos/task_context.rb', line 345

state_transition_call :reset_exception, 'EXCEPTION', nil

#resolve_connection_from(source, policy = Hash.new) ⇒ Object



642
643
644
645
646
647
648
# File 'lib/orocos/task_context.rb', line 642

def resolve_connection_from(source, policy = Hash.new)
    port = find_input_port(source.type,nil)
    if !port
        raise ArgumentError, "port #{source.name} does not match any input port of #{name}."
    end
    source.connect_to(port, policy)
end

#resolve_disconnection_from(source) ⇒ Object



650
651
652
653
654
655
656
657
# File 'lib/orocos/task_context.rb', line 650

def resolve_disconnection_from(source)
    each_input_port do |in_port|
        if in_port.type == source.type
            source.disconnect_from(in_port)
        end
    end
    nil
end

#rtt_stateObject

Reads the state announced by the task's getState() operation



226
227
228
229
# File 'lib/orocos/task_context.rb', line 226

def rtt_state
    value = CORBA.refine_exceptions(self) { do_state() }
    @state_symbols[value]
end

#save_conf(file, section_names = nil) ⇒ Object

Saves the current configuration into a file



310
311
312
# File 'lib/orocos/task_context.rb', line 310

def save_conf(file, section_names = nil)
    Orocos.conf.save(self,file,section_names)
end

#sendop(name, *args) ⇒ Object

Sends the required operation with the given argument

This is a shortcut for operation(name).sendop(*arguments)



586
587
588
# File 'lib/orocos/task_context.rb', line 586

def sendop(name, *args)
    operation(name).sendop(*args)
end

#startObject

:method: start

Starts the component, i.e. do the transition from STATE_STOPPED into STATE_RUNNING.

Raises StateTransitionFailed if the component was not in STATE_STOPPED state before the call, or if the component refused to do the transition (startHook() returned false)



334
# File 'lib/orocos/task_context.rb', line 334

state_transition_call :start, 'STOPPED', 'RUNNING'

#state_reader(policy = Hash.new) ⇒ Object

Returns a StateReader object that allows to flexibly monitor the task's state



181
182
183
184
185
186
187
188
# File 'lib/orocos/task_context.rb', line 181

def state_reader(policy = Hash.new)
    policy = Port.prepare_policy({:init => true, :type => :buffer, :size => 10}.merge(policy))

    reader = port('state').reader(policy)
    reader.extend StateReader
    reader.state_symbols = @state_symbols
    reader
end

#stopObject

:method: stop

Stops the component, i.e. do the transition from STATE_RUNNING into STATE_STOPPED.

Raises StateTransitionFailed if the component was not in STATE_RUNNING state before the call. The component cannot refuse to perform the transition (but can take an arbitrarily long time to do it).



356
# File 'lib/orocos/task_context.rb', line 356

state_transition_call :stop, 'RUNNING', 'STOPPED'

#tidObject

Returns the PID of the thread this task runs on

This is available only on oroGen task, for which oroGen adds an orogen_getPID operation that returns this information



214
215
216
217
218
219
220
221
222
223
# File 'lib/orocos/task_context.rb', line 214

def tid
    if !@tid
        if has_operation?('__orogen_getTID')
            @tid = operation('__orogen_getTID').callop()
        else
            raise ArgumentError, "#tid is available only on oroGen tasks, not #{self}"
        end
    end
    @tid
end

#to_async(options = Hash.new) ⇒ Object



79
80
81
82
83
# File 'lib/orocos/async/orocos.rb', line 79

def to_async(options = Hash.new)
    options[:name] ||= name
    options[:ior] ||= ior
    Orocos::Async::CORBA::TaskContext.new(options)
end

#to_proxy(options = Hash.new) ⇒ Object



85
86
87
88
89
90
# File 'lib/orocos/async/orocos.rb', line 85

def to_proxy(options = Hash.new)
    options[:use] ||= to_async
    # use name service to check if there is already 
    # a proxy for the task
    Orocos::Async.proxy(name,options)
end

#to_sObject



297
298
299
# File 'lib/orocos/task_context.rb', line 297

def to_s
    "#<TaskContext: #{self.class.name}/#{name}>"
end

#wait_for_state(state_name, timeout = nil, polling = 0.1) ⇒ Object

Waits for the task to be in state state_name for the specified amount of time

Raises RuntimeError on timeout



274
275
276
277
278
279
280
281
282
283
284
285
286
# File 'lib/orocos/task_context.rb', line 274

def wait_for_state(state_name, timeout = nil, polling = 0.1)
    state_name = state_name.to_sym

    start = Time.now
    peek_state
    while !@state_queue.include?(state_name)
        if timeout && (Time.now - start) > timeout
            raise "timing out while waiting for #{self} to be in state #{state_name}. It currently is in state #{current_state}"
        end
        sleep polling
        peek_state
    end
end