Hi
Just wanted to get opinions from C++ experts about the following:
I am building a simple code generator akin to the orocreate-pkg. The
code generator can be initialized with a file defining an arbitrary
number of ports. The list of ports is mutable and thus the ports
generated as C++ code are mutable too. The end product of code
generation is a TaskContext. The code generation is only allowed to
modifiy the header file for the TaskContext. A user is not expected to
edit the header file. All user code is added by the using in the
source file.
This is the initial header/source combination that compiles. Please
check it over and comment.
===HEADER===
/*
* Task_R_RT.hpp
*
* Created on: Jul 17, 2011
* Author: hugo
*/
#ifndef TASK_R_RT_HPP_
#define TASK_R_RT_HPP_
#include <rtt/RTT.hp
#include <rtt/Component.hp
using namespace RTT;
namespace KUL
{
class Task_R_RT: public RTT::TaskContext
{
InputPort<char> InPortB;
InputPort<char> InPortC;
OutputPort<char> OutPortA;
public:
Task_R_RT(const string& name);
};
Task_R_RT::Task_R_RT(string const& name = "Task_B") :
TaskContext(name)
{
this->ports()->addPort("InPortB", InPortB).doc(
"Input Port that does *not* raise an event.");
this->ports()->addPort("InPortC", InPortC).doc(
"Input Port that does *not* raise an event.");
this->ports()->addPort("OutPortA", OutPortA).doc(
"Output Port, here write our data to.");
}
}
ORO_CREATE_COMPONENT(KUL::Task_R_RT)
#endif /* TASK_R_RT_HPP_ */
====SOURCE====
/*
* Task_R_RT.cpp
*
* Created on: Jul 17, 2011
* Author: hugo
*/
#include <iostream>
#include "Task_R_RT.hpp"
bool configureHook()
{
std::cout << "Task_A configured !" << std::endl;
return true;
}
bool startHook()
{
std::cout << "Task_A started !" << std::endl;
return true;
}
void updateHook()
{
std::cout << "Task_A executes updateHook !" << std::endl;
}
void stopHook()
{
std::cout << "Task_A executes stopping !" << std::endl;
}
void cleanupHook()
{
std::cout << "Task_A cleaning up !" << std::endl;
}
-------
Some observations and question:
* KUL here would represent the namespace for an Orocos package. Thus
every Orocos package would have its own specific namespace.
* Here we are only create one component in a library yet a package can
have multiple components. It is my understanding there is a separate
macro for combining multiple component into one package. Where would
that macro be written in the header file(s) or would it be written
somewhere else?
* Do the methods in Task_R_RT.cpp [starHook(), updateHook()] actually
override the protected methods of the same names in
rtt/base/TaskCore.hpp?
-H
Separating User Code from Generated Code into Headers and Source
On 07/19/2011 10:12 PM, Hugo Garcia wrote:
> Hi
>
> Just wanted to get opinions from C++ experts about the following:
>
> I am building a simple code generator akin to the orocreate-pkg. The
> code generator can be initialized with a file defining an arbitrary
> number of ports. The list of ports is mutable and thus the ports
> generated as C++ code are mutable too. The end product of code
> generation is a TaskContext. The code generation is only allowed to
> modifiy the header file for the TaskContext. A user is not expected to
> edit the header file. All user code is added by the using in the
> source file.
Can I respectfully suggest that you have a look at orogen, which already
does more or less exactly that ?
Sylvain
Separating User Code from Generated Code into Headers and Source
On Thu, Jul 28, 2011 at 11:31, Sylvain Joyeux <sylvain [dot] joyeux [..] ...> wrote:
> On 07/19/2011 10:12 PM, Hugo Garcia wrote:
>>
>> Hi
>>
>> Just wanted to get opinions from C++ experts about the following:
>>
>> I am building a simple code generator akin to the orocreate-pkg. The
>> code generator can be initialized with a file defining an arbitrary
>> number of ports. The list of ports is mutable and thus the ports
>> generated as C++ code are mutable too. The end product of code
>> generation is a TaskContext. The code generation is only allowed to
>> modifiy the header file for the TaskContext. A user is not expected to
>> edit the header file. All user code is added by the using in the
>> source file.
>
> Can I respectfully suggest that you have a look at orogen, which already
> does more or less exactly that ?
>
> Sylvain
>
I did but the way the file for generating the code is created in a
different manner than your approach. The end result is still the same.
-H
Separating User Code from Generated Code into Headers and Source
On 07/28/2011 08:11 PM, Hugo Garcia wrote:
> On Thu, Jul 28, 2011 at 11:31, Sylvain Joyeux<sylvain [dot] joyeux [..] ...> wrote:
>> On 07/19/2011 10:12 PM, Hugo Garcia wrote:
>>> Hi
>>>
>>> Just wanted to get opinions from C++ experts about the following:
>>>
>>> I am building a simple code generator akin to the orocreate-pkg. The
>>> code generator can be initialized with a file defining an arbitrary
>>> number of ports. The list of ports is mutable and thus the ports
>>> generated as C++ code are mutable too. The end product of code
>>> generation is a TaskContext. The code generation is only allowed to
>>> modifiy the header file for the TaskContext. A user is not expected to
>>> edit the header file. All user code is added by the using in the
>>> source file.
>> Can I respectfully suggest that you have a look at orogen, which already
>> does more or less exactly that ?
>>
>> Sylvain
>>
> I did but the way the file for generating the code is created in a
> different manner than your approach. The end result is still the same.
I don't understand that statement.
orogen is mostly an API. You can parse any file description, create
(programatically) an orogen spec and generate the corresponding code.
Creating a parallel code generator is just fragmenting the "model-based"
tooling in the orocos ecosystem, which sucks big time.
Sylvain
Separating User Code from Generated Code into Headers and Source
On Fri, 29 Jul 2011, Sylvain Joyeux wrote:
> On 07/28/2011 08:11 PM, Hugo Garcia wrote:
>> On Thu, Jul 28, 2011 at 11:31, Sylvain Joyeux<sylvain [dot] joyeux [..] ...> wrote:
>>> On 07/19/2011 10:12 PM, Hugo Garcia wrote:
>>>> Hi
>>>>
>>>> Just wanted to get opinions from C++ experts about the following:
>>>>
>>>> I am building a simple code generator akin to the orocreate-pkg. The
>>>> code generator can be initialized with a file defining an arbitrary
>>>> number of ports. The list of ports is mutable and thus the ports
>>>> generated as C++ code are mutable too. The end product of code
>>>> generation is a TaskContext. The code generation is only allowed to
>>>> modifiy the header file for the TaskContext. A user is not expected to
>>>> edit the header file. All user code is added by the using in the
>>>> source file.
>>> Can I respectfully suggest that you have a look at orogen, which already
>>> does more or less exactly that ?
>>>
>>> Sylvain
>>>
>> I did but the way the file for generating the code is created in a
>> different manner than your approach. The end result is still the same.
> I don't understand that statement.
>
> orogen is mostly an API. You can parse any file description, create
> (programatically) an orogen spec and generate the corresponding code.
>
> Creating a parallel code generator is just fragmenting the "model-based"
> tooling in the orocos ecosystem, which sucks big time.
This is a dangerous statement :-) You have basically done the same thing:
there are tons of code generators "out there", in large-scale ecosystems
like Eclipse, for example, that you could have used. And since Hugo's job
is to integrate Orocos into the Eclipse ecosystem, it makes sense to use
the Model-to-Model and Model-to-Text tools that are supported there. The
issues to be still researched are: (i) is there a real difference in the
quality and sustainability of different model transformation tools, and
(ii) can we come up with a code generation workflow that is independent of
the transformation tool that is being used.
Note that I am just observing, not judging. :-)
> Sylvain
Herman
Separating User Code from Generated Code into Headers and Source
On Tue, Jul 19, 2011 at 10:12 PM, Hugo Garcia <hugo [dot] a [dot] garcia [..] ...> wrote:
> Hi
>
> Just wanted to get opinions from C++ experts about the following:
>
> I am building a simple code generator akin to the orocreate-pkg. The
> code generator can be initialized with a file defining an arbitrary
> number of ports. The list of ports is mutable and thus the ports
> generated as C++ code are mutable too. The end product of code
> generation is a TaskContext. The code generation is only allowed to
> modifiy the header file for the TaskContext. A user is not expected to
> edit the header file. All user code is added by the using in the
> source file.
>
> This is the initial header/source combination that compiles. Please
> check it over and comment.
It compiles but it's completely crap. This looks like an orocos-users
question btw.
>
> ===HEADER===
>
> /*
> * Task_R_RT.hpp
> *
> * Created on: Jul 17, 2011
> * Author: hugo
> */
>
> #ifndef TASK_R_RT_HPP_
> #define TASK_R_RT_HPP_
>
> #include <rtt/RTT.hp
> #include <rtt/Component.hp
This include belongs in the .cpp file
>
> using namespace RTT;
>
> namespace KUL
> {
> class Task_R_RT: public RTT::TaskContext
> {
> InputPort<char> InPortB;
> InputPort<char> InPortC;
> OutputPort<char> OutPortA;
>
> public:
> Task_R_RT(const string& name);
> };
>
> Task_R_RT::Task_R_RT(string const& name = "Task_B") :
> TaskContext(name)
> {
> this->ports()->addPort("InPortB", InPortB).doc(
> "Input Port that does *not* raise an event.");
> this->ports()->addPort("InPortC", InPortC).doc(
> "Input Port that does *not* raise an event.");
> this->ports()->addPort("OutPortA", OutPortA).doc(
> "Output Port, here write our data to.");
>
> }
This function would end up in every compilation unit. It belongs in
the .cpp file too.
> }
>
> ORO_CREATE_COMPONENT(KUL::Task_R_RT)
This macro belongs in the .cpp file.
>
> #endif /* TASK_R_RT_HPP_ */
>
>
> ====SOURCE====
>
> /*
> * Task_R_RT.cpp
> *
> * Created on: Jul 17, 2011
> * Author: hugo
> */
>
> #include <iostream>
> #include "Task_R_RT.hpp"
>
> bool configureHook()
> {
> std::cout << "Task_A configured !" << std::endl;
> return true;
> }
This doesn't do what you intend. You need to declare the
configureHook() function in your class and then implement it with:
bool Task_R_RT::configureHook() { ... }
>
> bool startHook()
> {
> std::cout << "Task_A started !" << std::endl;
> return true;
> }
>
> void updateHook()
> {
> std::cout << "Task_A executes updateHook !" << std::endl;
> }
>
> void stopHook()
> {
> std::cout << "Task_A executes stopping !" << std::endl;
> }
>
> void cleanupHook()
> {
> std::cout << "Task_A cleaning up !" << std::endl;
> }
>
> -------
>
> Some observations and question:
>
> * KUL here would represent the namespace for an Orocos package. Thus
> every Orocos package would have its own specific namespace.
That's wise.
>
> * Here we are only create one component in a library yet a package can
> have multiple components. It is my understanding there is a separate
> macro for combining multiple component into one package. Where would
> that macro be written in the header file(s) or would it be written
> somewhere else?
See http://www.orocos.org/stable/documentation/rtt/v2.x/api/html/Component_8...
and especially
http://www.orocos.org/stable/documentation/rtt/v2.x/api/html/Component_8...
>
> * Do the methods in Task_R_RT.cpp [starHook(), updateHook()] actually
> override the protected methods of the same names in
> rtt/base/TaskCore.hpp?
No. They are free functions, they don't belong to any class.
Peter
--
Orocos-Dev mailing list
Orocos-Dev [..] ...
http://lists.mech.kuleuven.be/mailman/listinfo/orocos-dev
Separating User Code from Generated Code into Headers and Source
Iteration #2
===Header===
/*
* Controller_RT.hpp
*
*/
#ifndef CONTROLLER_RT_HPP_
#define CONTROLLER_RT_HPP_
using namespace RTT;
namespace YouBotMotion
{
class Controller_RT: public RTT::TaskContext
{
InputPort<float> Position;
OutputPort<float> Velocity;
public:
Controller_RT(const string& name);
bool configureHook();
bool startHook();
void updateHook();
void stopHook();
void cleanupHook();
};
}
#endif /* CONTROLLER_RT_HPP_ */
===SOURCE===
#include <rtt/RTT.hp
#include <rtt/Component.hp
#include <iostream>
#include "Controller_RT.hpp"
using namespace RTT;
using namespace YouBotMotion;
Controller_RT::Controller_RT(string const& name = "Controller") :
TaskContext(name)
{
this->ports()->addPort( "Position", Position ).doc( "Input Port that
does *not* raise an event." );
this->ports()->addPort( "Velocity", Velocity ).doc( "Output Port,
here write our data to." );
std::cout << "Controller constructed !" <<std::endl;
}
bool Controller_RT::configureHook()
return true;
{
std::cout << "Controller configured !" <
}
bool Controller_RT::startHook()
return true;
{
std::cout << "Controller started !" <
}
void Controller_RT::updateHook()
}
{
std::cout << "Controller executes updateHook !" <
void Controller_RT::stopHook()
}
{
std::cout << "Controller executes stopping !" <
void Controller_RT::cleanupHook()
}
{
std::cout << "Controller cleaning up !" <
ORO_CREATE_COMPONENT(YouBotMotion::Controller_RT)
=======
>