This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

How to Create Instances Statically in Custom RTSC Packages



Hi All,

I have two modules Link and Robot, I need to create six instances of Link in the Robot module statically in the .xs file and use the instance object in the Robot.c taget implementation. How can i do this.

Thanks & Regards

Ragesh S. Kutty

 

  • Ragesh,
    there are two functionalities that you can use to access statically generated instances in your C code.
    First, you can use Program.global to attach static instances to it as described in the example in the linked documenation. The example refers to the configuration script as the location where you should populate Program.global, but Robot.xs will work just as well. Unfortunately, you can't create an array and attach it to Program.global, so you'll have to choose six different names for your instances:
    Program.global.inst0 = Link.create(...);
    ...
    Program.global.inst5 = Link.create(...);
    or you can do it in a loop
    for (var i =0; i < 5; i++) {
        Program.global["inst" + i] = Link.create(...);
    }
    Then, in your Robot.c file, you have to declare them as externs because you can't include <xdc/cfg/global.h>. That file doesn't exist at the time you will be compiling Robot.c.
    extern const Link_Handle inst0, inst1, ...;

    To use a different functionality, you should just create static instances without attaching them to Program.global.
    for (var i =0; i < 5; i++) {
        Link.create(...);
    }
    and then in Robot.c, you'll call two functions documented in xdc.runtime.IModule. The first function retrieves a number of static instances defined for Link.
    Int count;
    count = Link_Object_count();
    The second function allows you to get a handle to each of the statically created instances:
    Link_Handle handle;
    for (i = 0; i < count; i ++) {
        handle = Link_Object_get(NULL, i);
    }

    The second approach might look easier, but there are some disadvantages. If a user or any other module creates static instance of Link, you may not be able to differentiate between the ones that you created and the others. You could give names to your instances, but there is a memory cost attached to it. Also, I assumed for both solutions that Link and Robot are always used together. However, if they can be used separately you'll need additional code that guards instance creation and usage code to run only when the module Link is actually used.

  • Hello Sasha,

    I have defined Program.global.Sh_Lnk = Link.create(ShLnkParams); in the Robot.xs file and added extern const Link_Handle Sh_Lnk; in Robot.c file. the instance Sh_Lnk handle has some instance parameters like Length, Mass etc. when i use Float Length = Sh_Lnk->L; in Robot.c i am getting error - "Robot.c pointer to incomplete class type is not allowed". Also i wanted to initialize some module state variables of Robot module in Robot.xs file with the instance handler Sh_Lnk. That returns another error - "Sh_Lnk" is not defined, when i take this package in ccs and build. I am attaching the Link and robot code.

    /*
    * ======== systcs/system/Link.xdc ========
    */

    /*! Link module contains Link Properties of the Robot */

    module Link {

    instance:

    create();

    /*! Link length */
    config Float Length = 0;

    /*! Link Mass */
    config Float Mass = 0;

    /*! Center of gravity of the Link */
    config Float CenterOfGrv = 0;

    /*! Link Offset */
    config Float Offset = 0;

    internal:

    struct Instance_State {
    Float L;
    Float M;
    Float Lcg;
    Float Offset;
    };

    }

    /*
    * ======== systcs/system/Link.xs ========
    */


    function instance$static$init(obj, params)
    {
    obj.L = params.Length;
    obj.M = params.Mass;
    obj.Lcg = params.CenterOfGrv;
    obj.Offset = params.Offset;
    }

    /*
    * ======== systcs/system/Robot.xs ========
    */

    var Link = null;

    function module$use()
    {
    Link = xdc.useModule('systcs.system.Link');
    }

    function module$static$init(obj,param)
    {

    var ShLnkParams = new Link.Params();
    ShLnkParams.Length = param.Sh_Lnk_L*1000;
    ShLnkParams.Mass = param.Sh_Lnk_M;
    ShLnkParams.CenterOfGrv = param.Sh_Lnk_Lcg;
    ShLnkParams.Offset = param.Sh_Lnk_Offset*1000;

    Program.global.Sh_Lnk = Link.create(ShLnkParams);

    obj.l1 = Sh_Lnk.L*1000;           /*Returns error - "Sh_Lnk" is not defined*/
    obj.d = Sh_Lnk.Offset*1000;
    }


    /*
    * ======== systcs/system/Robot.c ========
    */

    #include <xdc/std.h>
    #include <F28M35x_Ipc.h>
    #include <math.h>
    #include <systcs/system/Link.h>
    #include "package/internal/Robot.xdc.h"

    extern const Link_Handle Sh_Lnk;

    /****************************************************************************************

    * Function: Robot_getFeedForwardComp
    * Project: SysconDSP
    * Author: Ragesh S. Kutty
    * Comment: Function which calculates FeedForward Torque, given pos in acs, Jnt velocity and acceleration
    ****************************************************************************************/
    Void Robot_getFeedForwardComp( Float inACSPos[Robot_ALL_JNTS],
    Float inACSVel[Robot_ALL_JNTS],
    Float inACSAccel[Robot_ALL_JNTS],
    Float outFFComp[Robot_ALL_JNTS]
    )
    {
    Float Length = Sh_Lnk->L;   /*Returns error - "Robot.c pointer to incomplete class type is not allowed"

    }


    Thanks & Regards

    Ragesh S. Kutty


  • Ragesh,
    you can't use Link handles to reach into the internal state of Link instance. You can use handles only to pass them to instance functions, however you did not define any. The standard way to access instance state would be to define get/set functions for L and other elements of the internal state.

    In Robot.xs you only defined a property of Program.global that's called "Sh_Lnk". That does not mean there is now a global JavaScript variable called "Sh_Lnk". You can create one if you want to. Instead of the line that creates a Link instance and assigns it to Program.global, you can do:
    var Sh_Lnk = Link.create(ShLnkParams);
    Program.global.Sh_Lnk = Sh_Lnk;

    Now, you have a global variable Sh_Lnk that you can use to assign to obj.