private string getGyroStatus <T>(CBlockGroup <T> group) where T : class, IMyTerminalBlock
    {
        if (!group.isAssignable <IMyGyro>())
        {
            return("");
        }
        string result = "";
        float  yaw    = 0;
        float  pitch  = 0;
        float  roll   = 0;

        foreach (IMyGyro block in group.blocks())
        {
            yaw   += block.Yaw;
            pitch += block.Pitch;
            roll  += block.Roll;
        }
        result += $"YPR: {yaw/group.count():f3}:{pitch/group.count():f3}:{roll/group.count():f3} ";
        return(result);
    }
    public void showStatus <T>(CBlockGroup <T> group, int position) where T : class, IMyTerminalBlock
    {
        string result = $"[{group.subtypeName()}] {group.purpose()} ";

        if (!group.empty())
        {
            result += $"({group.count()}) "
                      + getPistonsStatus <T>(group)
                      + getConnectorsStatus <T>(group)
                      + getMergersStatus <T>(group)
                      + getProjectorsStatus <T>(group)
                      + getDrillsStatus <T>(group)
                      + getRotorsStatus <T>(group)
                      + getGyroStatus <T>(group)
                      + getFunctionaBlocksStatus <T>(group)
            ;
        }
        else
        {
            result += $" Группа {group.groupName()} пуста";
        }
        echo_at(result, position);
    }