The double brackets [[..]] mean Part and the single brackets [ro] are part of the syntax for a function call. See also the tutorial Parts of Expressions.
Breaking down the components of a computation can be an effective way to figure how code works, especially when the output is small enough to fit on a screen. To see the effect of the brackets, one might execute each of the lines below and note how Part affects the output:
NDSolve[{y''[x] + y[x] == 0, y[0] == 1, y'[0] == 0}, y, {x, 0, 10}]
NDSolve[{y''[x] + y[x] == 0, y[0] == 1, y'[0] == 0}, y, {x, 0, 10}][[1]]
NDSolve[{y''[x] + y[x] == 0, y[0] == 1, y'[0] == 0}, y, {x, 0, 10}][[1]][[1]]
NDSolve[{y''[x] + y[x] == 0, y[0] == 1, y'[0] == 0}, y, {x, 0, 10}][[1]][[1]][[2]]
NDSolve[{y''[x] + y[x] == 0, y[0] == 1, y'[0] == 0}, y, {x, 0, 10}][[1]][[1]][[2]][ro]
One can combine the Part calls into one:
NDSolve[{y''[x] + y[x] == 0, y[0] == 1, y'[0] == 0}, y, {x, 0, 10}][[1, 1, 2]][ro]
One can use the shortcut NDSolveValue, introduced in V9, to get the same output (note the y[ro] inside):
NDSolveValue[{y''[x] + y[x] == 0, y[0] == 1, y'[0] == 0}, y[ro], {x, 0, 10}]
And one can use the old-school form of ReplaceAll and First, frequently found in the documentation:
y[ro] /. First@NDSolve[{y''[x] + y[x] == 0, y[0] == 1, y'[0] == 0}, y, {x, 0, 10}]
Finally, you might want to address a potential bug in your definition of psr. It contains the global symbol f and depends on f being undefined. If somehow f gets defined, it will mess up psr. Localizing the symbol f with Module will protect it.
psr[ro, om, a_] := Module[{f},
NDSolveValue[{ f ' [ t ] - rhs[ t, f [ t ], om ] == 0, f [ a ] == 1}, f[ro], {t, a, 1}]
];